Pots POJ - 3414
bfs题;
标注的状态应为2容器的体积,因为每种2容器的体积都应该只由一种状态达到。
不使用队列
#include<stdio.h>
#include<string.h>
struct node{
int now_x;
int now_y;
int step;
int howcome;
int before;
}ll[10050];
int head=1,tail=1,c[150000],cnt=0,vis[150][150];
int x,y,z;
void bfs()
{
int lx,ly;
while(head<=tail)
{
lx=ll[head].now_x;
ly=ll[head].now_y;
// printf("%d %d %d %d %d\n",head,tail,ll[head].step,lx,ly);
if(lx==z||ly==z)
{
printf("%d\n",ll[head].step);
// printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
int w=head;
while(1)
{
c[cnt]=ll[w].howcome;
cnt++;
// printf("%d\n",ll[w].howcome);
w=ll[w].before;
if(w==1)
break;
}
for(int k=cnt-1;k>=0;k--)
{
if(c[k]==3)
printf("FILL(1)\n");
if(c[k]==4)
printf("FILL(2)\n");
if(c[k]==1)
printf("DROP(1)\n");
if(c[k]==2)
printf("DROP(2)\n");
if(c[k]==5)
printf("POUR(1,2)\n");
if(c[k]==6)
printf("POUR(2,1)\n");
}
return ;
}
if(lx>0&&vis[0][ly]==0) //倒x的水。
{
tail++;
ll[tail].now_x=0;
ll[tail].now_y=ly;
int llx=ll[tail].now_x;
int lly=ll[tail].now_y;
vis[llx][lly]=1;
ll[tail].step=ll[head].step+1;
ll[tail].howcome=1;
ll[tail].before=head;
/* if(ll[tail].now_x==z||ll[tail].now_y==z)
{
printf("%d\n",ll[tail].step);
}*/
}
if(ly>0&&vis[lx][0]==0) //倒y的水。
{
tail++;
ll[tail].now_x=lx;
ll[tail].now_y=0;
int llx=ll[tail].now_x;
int lly=ll[tail].now_y;
vis[llx][lly]=1;
ll[tail].step=ll[head].step+1;
ll[tail].howcome=2;
ll[tail].before=head;
/* if(ll[tail].now_x==z||ll[tail].now_y==z)
{
printf("%d\n",ll[tail].step);
}*/
}
if(lx<x&&vis[x][ly]==0) //把x的水装满。
{
tail++;
ll[tail].now_x=x;
ll[tail].now_y=ly;
int llx=ll[tail].now_x;
int lly=ll[tail].now_y;
vis[llx][lly]=1;
ll[tail].step=ll[head].step+1;
ll[tail].howcome=3;
ll[tail].before=head;
/* if(ll[tail].now_x==z||ll[tail].now_y==z)
{
printf("%d\n",ll[tail].step);
}*/
}
if(ly<y&&vis[lx][y]==0) //把y的水装满。
{
tail++;
ll[tail].now_x=lx;
ll[tail].now_y=y;
int llx=ll[tail].now_x;
int lly=ll[tail].now_y;
vis[llx][lly]=1;
ll[tail].step=ll[head].step+1;
ll[tail].howcome=4;
ll[tail].before=head;
/* if(ll[tail].now_x==z||ll[tail].now_y==z)
{
printf("%d\n",ll[tail].step);
}*/
}
if(lx>0&&ly<y) //把x的水倒入y中。
{
int oy1=lx+ly-y;
int oy2=lx+ly;
if(lx+ly>y&&vis[oy1][y]==0)
{
tail++;
ll[tail].now_x=lx+ly-y;
ll[tail].now_y=y;
int llx=ll[tail].now_x;
int lly=ll[tail].now_y;
vis[llx][lly]=1;
ll[tail].step=ll[head].step+1;
ll[tail].howcome=5;
ll[tail].before=head;
}
if(lx+ly<=y&&vis[0][oy2]==0)
{
tail++;
ll[tail].now_x=0;
ll[tail].now_y=lx+ly;
int llx=ll[tail].now_x;
int lly=ll[tail].now_y;
vis[llx][lly]=1;
ll[tail].step=ll[head].step+1;
ll[tail].howcome=5;
ll[tail].before=head;
}
}
if(ly>0&&lx<x) //把y的水倒入x中。
{
int ox1=lx+ly-x;
int ox2=lx+ly;
if(lx+ly>x&&vis[x][ox1]==0)
{
tail++;
ll[tail].now_x=x;
ll[tail].now_y=lx+ly-x;
int llx=ll[tail].now_x;
int lly=ll[tail].now_y;
vis[llx][lly]=1;
ll[tail].step=ll[head].step+1;
ll[tail].howcome=6;
ll[tail].before=head;
}
if(lx+ly<=x&&vis[ox2][0]==0)
{
tail++;
ll[tail].now_x=lx+ly;
ll[tail].now_y=0;
int llx=ll[tail].now_x;
int lly=ll[tail].now_y;
vis[llx][lly]=1;
ll[tail].step=ll[head].step+1;
ll[tail].howcome=6;
ll[tail].before=head;
}
}
head++;
}
printf("impossible\n");
return ;
}
int main()
{
scanf("%d%d%d",&x,&y,&z);
memset(vis,0,sizeof(vis));
ll[1].now_x=0;
ll[1].now_y=0;
ll[1].step=0;
bfs();
return 0;
}
使用队列;
# include<stdio.h>
# include <queue>
# include <string.h>
using namespace std;
# define max 110
int A,B,C;
char num[12][12] = {"FILL(1)","FILL(2)", "DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};
struct node
{
int x,y,step,op;//OP是用来最后作为num数组的下标指引路径
}v[max][max];
struct point
{
int x, y;
};
void DFS(int x, int y)//用递归来返回路径
{
if(x == 0 && y == 0)
return;
DFS(v[x][y].x, v[x][y].y);
printf("%s\n",num[ v[x][y].op ]);
}
int BFS( point t )
{
queue<point>Q;
v[0][0].step = 1;
Q.push(t);
while(Q.size())
{
point s = Q.front();
Q.pop();
if(s.x == C || s.y == C)
{
printf("%d\n", v[s.x][s.y].step-1);
DFS(s.x, s.y);
return 0;
}
for(int i = 0; i<6; i++)
{
point q = s;
if(i == 0)
{
q.x = A;
}
else if(i == 1)
{
q.y = B;
}
else if(i == 2)
{
q.x = 0;
}
else if( i== 3)
{
q.y = 0;
}
else if(i == 4)
{
if(q.x+q.y <= B)
q.y += q.x, q.x = 0;//把A里面的水全倒B里面
else
q.x -= (B-q.y), q.y = B;//把B倒满
}
else
{
if(q.x+q.y <= A)
q.x += q.y, q.y = 0;
else
q.y -= (A-q.x), q.x = A;
}
if( v[q.x][q.y].step == 0)//用当下当成下标,将以前当成值
{
v[q.x][q.y].step = v[s.x][s.y].step +1;
v[q.x][q.y].x = s.x;
v[q.x][q.y].y = s.y;
v[q.x][q.y].op = i;//路径下标指引所以上面0-5的操作要和路径数组里要求的一致
Q.push(q);
}
}
}
return -1;
}
int main(void)
{
while(~scanf("%d%d%d",&A,&B,&C))
{
memset(v, 0, sizeof(v));
point s;
s.x = 0;
s.y = 0;
int ans = BFS(s);
if(ans == -1)
printf("impossible\n");
}
return 0;
}