利用bfs解题,以三个杯子中现有水量作为一个“状态”,从一个状态不断扩展新的状态加入排队数组,这样既可保证找到目标水量时是经过了最少次数的倒水操作。
扩展新的状态节点是个稍微难一点的地方,先计算出i给j能倒得水量amount,等于i所剩水与j所差水的最小值。然后当amount!=0时进行倒水操作。vis是判重数组,只需要二维既可,因为三个杯子的水总量是不变的,两个杯子的水量相同时就表明是同一个状态。
难度不大,细心既可。
转载请注明出处,谢谢
http://blog.csdn.net/monkeyduck
#include<iostream>
#include<cstring>
using namespace std;
int vol[3],d,n,front,rear;
bool flag,vis[201][201];
struct Node
{
int water[3],s;
};
Node result,state[40001];
void bfs()
{
int i,j;
front=rear=0;
Node init,tnode;
init.water[0]=0;init.water[1]=0;init.water[2]=vol[2];init.s=0;
vis[0][0]=1;
state[rear++]=init;
while(front<rear)
{
tnode=state[front++];
if (tnode.water[0]==d||tnode.water[1]==d||tnode.water[2]==d)
{
flag=1;
result=tnode;
break;
}
for (i=0;i<3;i++)
{
for (j=0;j<3;j++)
{
if (i!=j)
{
int amount=tnode.water[i]<vol[j]-tnode.water[j]?tnode.water[i]:vol[j]-tnode.water[j];
if (amount!=0)
{
Node nNode;
for (int k=0;k<3;k++)
nNode.water[k]=tnode.water[k];
nNode.water[i]=nNode.water[i]-amount;
nNode.water[j]=nNode.water[j]+amount;
nNode.s=tnode.s+amount;
if (!vis[nNode.water[0]][nNode.water[1]])
{
vis[nNode.water[0]][nNode.water[1]]=1;
state[rear++]=nNode;
}
}
}
}
}
}
}
int main()
{
cin>>n;
while(n--)
{
cin>>vol[0]>>vol[1]>>vol[2]>>d;
flag=0;
memset(vis,0,sizeof(vis));
bfs();
if (flag)
cout<<result.s<<" "<<d<<endl;
else
{
for (int i=d-1;i>=0;i--)
{
for (int j=0;j<=rear;j++)
{
Node nn=state[j];
if (nn.water[0]==i||nn.water[1]==i||nn.water[2]==i)
{
cout<<nn.s<<" "<<i<<endl;
flag=1;
break;
}
}
if (flag) break;
}
}
}
return 0;
}