题意:两个杯子相互倒水问题。
可以把一个杯子倒满,或者把一个杯子倒空,或者把一个杯子中的水倒入另外一个杯子中直到自己为空或者另外一个杯子满了为止,
最后输出倒法,
思路:隐式图BFS,一样用一个二维数组标记状态,加一个RE数组标记是从哪个位置转移过来的。这样可以在最后进行路径还原。
上代码。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
bool vis[105][105];
struct P{
int v[2];
};
struct N{
int x,y;
int fangshi;
int z,y1;
}re[105][105];
int d[105][105];
int A,B,C;
void init()
{
for(int i=0;i<=A;i++)
for(int j=0;j<=B;j++)
{
re[i][j].x=i;
re[i][j].y=j;
}
}
void huanyuan(int x,int y)
{
if(re[x][y].x==0&&re[x][y].y==0)
{
if(re[x][y].fangshi==1)
printf("FILL(%d)\n",re[x][y].z);
else if(re[x][y].fangshi==2)
printf("DROP(%d)\n",re[x][y].z);
else printf("POUR(%d,%d)\n",re[x][y].z,re[x][y].y1);
return ;
}
else
{
huanyuan(re[x][y].x,re[x][y].y);
if(re[x][y].fangshi==1)
printf("FILL(%d)\n",re[x][y].z);
else if(re[x][y].fangshi==2)
printf("DROP(%d)\n",re[x][y].z);
else printf("POUR(%d,%d)\n",re[x][y].z,re[x][y].y1);
}
}
void bfs()
{
queue<P> q;
P p1;
memset(p1.v,0,sizeof(p1.v));
memset(vis,0,sizeof(vis));
q.push(p1);
vis[0][0]=1;
memset(d,-1,sizeof(d));
d[0][0]=0;
bool flag=0;
while(q.size())
{
P p=q.front();
q.pop();
if(p.v[0]==C||p.v[1]==C)
{
printf("%d\n",d[p.v[0]][p.v[1]]);
huanyuan(p.v[0],p.v[1]);
flag=1;
break;
}
for(int i=0;i<2;i++)
{
int r;
if(i==0) r=A;
else r=B;
if(p.v[i]!=0)
{
if(i==0)
{
int nx=0,ny=p.v[1];
if(!vis[nx][ny])
{
d[nx][ny]=d[p.v[0]][p.v[1]]+1;
re[nx][ny].x=p.v[0];
re[nx][ny].y=p.v[1];
re[nx][ny].fangshi=2;
re[nx][ny].z=1;
P point;
point.v[0]=nx;
point.v[1]=ny;
vis[nx][ny]=1;
q.push(point);
}
if(p.v[1]!=B)
{
int nx=0;ny=p.v[0]+p.v[1];
if(ny>B)
{
nx=ny-B;
ny=B;
}
if(!vis[nx][ny])
{
vis[nx][ny]=1;
d[nx][ny]=d[p.v[0]][p.v[1]]+1;
re[nx][ny].x=p.v[0];
re[nx][ny].y=p.v[1];
re[nx][ny].fangshi=3;
re[nx][ny].z=1;
re[nx][ny].y1=2;
P point;
point.v[0]=nx;
point.v[1]=ny;
q.push(point);
}
}
}
else
{
int nx=p.v[0],ny=0;
if(!vis[nx][ny])
{
vis[nx][ny]=1;
d[nx][ny]=d[p.v[0]][p.v[1]]+1;
re[nx][ny].x=p.v[0];
re[nx][ny].y=p.v[1];
re[nx][ny].fangshi=2;
re[nx][ny].z=2;
P point;
point.v[0]=nx;
point.v[1]=ny;
q.push(point);
}
if(p.v[0]!=A)
{
int nx=p.v[0]+p.v[1];ny=0;
if(nx>A)
{
ny=nx-A;
nx=A;
}
if(!vis[nx][ny])
{
vis[nx][ny]=1;
d[nx][ny]=d[p.v[0]][p.v[1]]+1;
re[nx][ny].x=p.v[0];
re[nx][ny].y=p.v[1];
re[nx][ny].fangshi=3;
re[nx][ny].z=2;
re[nx][ny].y1=1;
P point;
point.v[0]=nx;
point.v[1]=ny;
q.push(point);
}
}
}
}
else if((i==0&&p.v[i]!=A)||(i==1&&p.v[i]!=B))
{
if(i==0)
{
int nx=A,ny=p.v[1];
if(!vis[nx][ny])
{
vis[nx][ny]=1;
d[nx][ny]=d[p.v[0]][p.v[1]]+1;
re[nx][ny].x=p.v[0];
re[nx][ny].y=p.v[1];
re[nx][ny].fangshi=1;
re[nx][ny].z=1;
P point;
point.v[0]=nx;
point.v[1]=ny;
q.push(point);
}
}
else
{
int nx=p.v[0],ny=B;
if(!vis[nx][ny])
{
vis[nx][ny]=1;
d[nx][ny]=d[p.v[0]][p.v[1]]+1;
re[nx][ny].x=p.v[0];
re[nx][ny].y=p.v[1];
re[nx][ny].fangshi=1;
re[nx][ny].z=2;
P point;
point.v[0]=nx;
point.v[1]=ny;
q.push(point);
}
}
}
}
}
if(flag==0)
printf("impossible\n");
}
int main()
{
while(scanf("%d%d%d",&A,&B,&C)!=EOF)
{
init();
bfs();
}
}