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;
}