http://acm.nyist.net/JudgeOnline/problem.php?pid=21
题目思路:我用BFS实现。共有三个水杯,最大水量为100,全部状态最多有100*100*100=1000000种,则可开一个三维数组标记已经产生过的状态,减少搜索次数。
每次将三个水杯中有水的杯子倒往其他两个水杯,则每次最多入队六个状态。实现思想简单,所以代码较多。
语文老师死得早,描述的一塌糊涂,请见谅:
#include<stdio.h>
#include<string.h>
#define MAX 110
int map[MAX][MAX][MAX];
int sx,sy,sz,ex,ey,ez;
int flag;
typedef struct node
{
int x,y,z,step;
}node;
node queue[MAX*MAX*MAX];
int step;
void bfs()
{
int front=0,rear=0;
queue[0].x=sx;
queue[0].y=0;
queue[0].z=0;
queue[0].step=0;
map[sx][0][0]=1;
rear++;
while (front<rear)
{
node tail=queue[front++];
//printf("%d %d %d %d\n",tail.x,tail.y,tail.z,tail.step);
if (tail.x==ex&&tail.y==ey&&tail.z==ez)
{
step=tail.step;
break;
}
int dx,dy,dz;
if (tail.x>0) //如果第一个水杯有水
{
if (tail.y<sy) 当第一个水杯有水,且第二个水杯还有剩余空间。
{
if (tail.x-(sy-tail.y)<0) //当一个水杯有水,且第二个水杯有剩余空间,但第一个水杯的水量小于第二个水杯的剩余空间
{
dx=0;
dy=tail.y+tail.x;
}
else
{
dx=tail.x-(sy-tail.y);
dy=sy;
}
dz=tail.z;
//printf("%d %d %d\n",dx,dy,dz);
if (!map[dx][dy][dz]) //如果当前状态没有遇到过,则入队
{
queue[rear].x=dx;
queue[rear].y=dy;
queue[rear].z=dz;
map[dx][dy][dz]=1;
queue[rear++].step=tail.step+1;
}
}
//以下原理类似。
if (tail.z<sz)
{
if (tail.x-(sz-tail.z)<0)
{
dx=0;
dz=tail.z+tail.x;
}
else
{
dx=tail.x-(sz-tail.z);
dz=sz;
}
dy=tail.y;
if (!map[dx][dy][dz])
{
queue[rear].x=dx;
queue[rear].y=dy;
queue[rear].z=dz;
map[dx][dy][dz]=1;
queue[rear++].step=tail.step+1;
}
}
}
if (tail.y>0)
{
if (tail.x<sx)
{
if (tail.y-(sx-tail.x)<0)
{
dy=0;
dx=tail.y+tail.x;
}
else
{
dy=tail.y-(sx-tail.x);
dx=sx;
}
dz=tail.z;
if (!map[dx][dy][dz])
{
queue[rear].x=dx;
queue[rear].y=dy;
queue[rear].z=dz;
map[dx][dy][dz]=1;
queue[rear++].step=tail.step+1;
}
}
if (tail.z<sz)
{
if (tail.y-(sz-tail.z)<0)
{
dy=0;
dz=tail.z+tail.y;
}
else
{
dy=tail.y-(sz-tail.z);
dz=sz;
}
dx=tail.x;
if (!map[dx][dy][dz])
{
queue[rear].x=dx;
queue[rear].y=dy;
queue[rear].z=dz;
map[dx][dy][dz]=1;
queue[rear++].step=tail.step+1;
}
}
}
if (tail.z>0)
{
if (tail.y<sy)
{
if (tail.z-(sy-tail.y)<0)
{
dz=0;
dy=tail.y+tail.z;
}
else
{
dz=tail.z-(sy-tail.y);
dy=sy;
}
dx=tail.x;
if (!map[dx][dy][dz])
{
queue[rear].x=dx;
queue[rear].y=dy;
queue[rear].z=dz;
map[dx][dy][dz]=1;
queue[rear++].step=tail.step+1;
}
}
if (tail.x<sx)
{
if (tail.z-(sx-tail.x)<0)
{
dz=0;
dx=tail.z+tail.x;
}
else
{
dz=tail.z-(sx-tail.x);
dx=sx;
}
dy=tail.y;
if (!map[dx][dy][dz])
{
queue[rear].x=dx;
queue[rear].y=dy;
queue[rear].z=dz;
map[dx][dy][dz]=1;
queue[rear++].step=tail.step+1;
}
}
}
//printf("%d %d\n",front,rear);
}
}
int main()
{
int t;
while (~scanf("%d",&t))
{
while (t--)
{
step=-1;
scanf("%d%d%d",&sx,&sy,&sz);
scanf("%d%d%d",&ex,&ey,&ez);
memset(map,0,sizeof(map));
if (sx>=ex+ey+ez) //如果最终状态所需的水大于初始时的水量,直接剪掉。
bfs();
printf("%d\n",step);
}
}
return 0;
}