倒水问题
设大,中,小3个杯子的容量分别为a,b,c。最初只有大杯子装满水,其他两个为空。最少要多少步让某一个杯子中有x升。0<c<b<a<1000
输入:
6 3 1
4
10 7 3
5
输出:
6 0 0
3 3 0
3 2 1
4 2 0
minimum steps:3
10 0 0
3 7 0
3 4 3
6 4 0
6 1 3
9 1 0
9 0 1
2 7 1
2 5 3
minimum steps:8
1 #include<iostream> 2 #include<cstring> 3 #include<iomanip> 4 #define mem(a) memset(a,0,sizeof(a)) 5 using namespace std; 6 const int MAXN=1000+10; 7 int q[MAXN*MAXN],fa[MAXN][MAXN],vis[MAXN][MAXN],step[MAXN][MAXN]; 8 int a,b,c,m; 9 void print(int state)//打印步骤 10 { 11 int x=state/1000,y=state%1000,z; 12 z=a-x-y; 13 if(state==q[0]){ 14 cout<<setw(4)<<x<<" "<<setw(4)<<y<<" "<<setw(4)<<z<<endl; 15 return; 16 } 17 else { 18 print(fa[x][y]); 19 cout<<setw(4)<<x<<" "<<setw(4)<<y<<" "<<setw(4)<<z<<endl; 20 } 21 } 22 void bfs() 23 { 24 mem(vis);mem(step); 25 int x=a,y=0,z; 26 int rear=0,front=0,u=x*1000+y; 27 q[rear++]=u;vis[x][y]=1; 28 for(;;) 29 { 30 u=q[front++];//队列前面取出一个 31 x=u/1000;y=u%1000;z=a-x-y;//x是a的量,y-〉b,z-〉c 32 if(x==m||y==m||z==m)//一旦有满足条件的就打印并结束搜索 33 { 34 print(u); 35 cout<<"minimum steps:"<<step[x][y]<<endl; 36 return ; 37 } 38 int v; 39 if(x)//a不为空 40 { 41 if(x>=b-y)v=(x-(b-y))*1000+b;else v=x+y;//把a的倒进b 42 if(!vis[v/1000][v%1000])//如果没有搜索到过 43 { 44 vis[v/1000][v%1000]=1;//标记已走过 45 q[rear++]=v;//放入队列尾部 46 fa[v/1000][v%1000]=u;//记录父节点 47 step[v/1000][v%1000]=step[x][y]+1;//步数加一 48 } 49 if(x>=c-z)v=(x-(c-z))*1000+y;else v=y;//把a的倒进c 50 if(!vis[v/1000][v%1000]){vis[v/1000][v%1000]=1;q[rear++]=v;fa[v/1000][v%1000]=u;step[v/1000][v%1000]=step[x][y]+1;} 51 } 52 if(y)//b不为空 53 { 54 v=(x+y)*1000;//b倒进a 55 if(!vis[v/1000][v%1000]){vis[v/1000][v%1000]=1;q[rear++]=v;fa[v/1000][v%1000]=u;step[v/1000][v%1000]=step[x][y]+1;} 56 if(y>=c-(z))v=x*1000+(y-(c-(z)));else v=x*1000;//b倒进c 57 if(!vis[v/1000][v%1000]){vis[v/1000][v%1000]=1;q[rear++]=v;fa[v/1000][v%1000]=u;step[v/1000][v%1000]=step[x][y]+1;} 58 } 59 if(z)//c不为空 60 { 61 v=(x+z)*1000+y;//c倒进a 62 if(!vis[v/1000][v%1000]){vis[v/1000][v%1000]=1;q[rear++]=v;fa[v/1000][v%1000]=u;step[v/1000][v%1000]=step[x][y]+1;} 63 if(z>=b-y)v=x*1000+b;else v=x*1000+a-x;//c倒进b 64 if(!vis[v/1000][v%1000]){vis[v/1000][v%1000]=1;q[rear++]=v;fa[v/1000][v%1000]=u;step[v/1000][v%1000]=step[x][y]+1;} 65 } 66 } 67 } 68 int main() 69 { 70 while(cin>>a>>b>>c>>m) 71 { 72 bfs(); 73 cout<<endl; 74 } 75 return 0; 76 }