倒水问题

 

设大,中,小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 }

 

posted @ 2013-02-07 18:49  再见~雨泉  阅读(236)  评论(0编辑  收藏  举报