POJ 3414 -- Pots

 POJ 3414 -- Pots

题意:

给出了两个瓶子的容量A,B, 以及一个目标水量C,

对A、B可以有如下操作:

FILL(i)        fill the pot i (1 ≤ i ≤ 2) from the tap;

DROP(i)      empty the pot i to the drain;

POUR(i,j)    pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).

问经过哪几个操作后能使得任意一个瓶子的残余水量为C。

若不可能得到则输出impossible

解题思路:

6入口bfs,啊...很典型的bfs...

  1 #include<iostream>
  2 #include<cstring>
  3 using namespace std;
  4 const int maxn = 101+5;//杯子中水的水量的取值范围为0~100
  5 ///定义6个动作,使用数组下标0~5存储
  6 const char* action[] = {"FILL(1)","FILL(2)","POUR(1,2)",
  7                         "POUR(2,1)","DROP(1)","DROP(2)"};
  8 int a,b,c;
  9 struct node{
 10 int anum,bnum;//记录节点,A中的水量,B中的水量
 11 int index;//记录action数组的下标,父节点是通过什么动作到达当前节点
 12 int deep;//记录深度
 13 int par;//记录父节点
 14 };
 15 ///为防止访问相同的结点,使用二维数组visit[i][j],
 16 ///表示A中水量为i,B中水量为j时的状态是否被访问过。
 17 bool visit[maxn][maxn];
 18 
 19 ///因为重复的结点不会访问,所以最多的结点数为maxn*maxn
 20 node queue[maxn*maxn];
 21 int ans[maxn*maxn];
 22 
 23 void change(int na,int nb,int &ta,int &tb,int i)
 24 {///"FILL(1)","FILL(2)","POUR(1,2)","POUR(2,1)","DROP(1)","DROP(2)"
 25     if(i == 0)//"FILL(1)"
 26     {
 27         ta = a;tb = nb;
 28     }
 29     else if(i==1)
 30     {
 31         ta = na;tb = b;
 32     }
 33     else if(i==2)
 34     {
 35         if(na>=(b-nb))///把b倒满
 36         {
 37             ta = na - (b-nb);tb = b;
 38         }
 39         else{///把a倒空
 40             ta = 0;tb = na+nb;
 41         }
 42     }
 43     else if(i==3)
 44     {
 45         if(nb>=(a-na))///把a倒满
 46         {
 47             tb = nb - (a-na);ta = a;
 48         }
 49         else{///把b倒空
 50             tb = 0;ta = nb+na;
 51         }
 52     }
 53     else if(i==4)
 54     {
 55         ta = 0;tb = nb;
 56     }
 57     else{
 58         tb = 0;ta = na;
 59     }
 60 }
 61 
 62 ///六入口的bfs
 63 bool bfs()
 64 {
 65     ///定义状态
 66     queue[0].anum = 0;
 67     queue[0].bnum = 0;
 68     queue[0].deep = 0;
 69     queue[0].index = -1;
 70     queue[0].par = -1;
 71     visit[0][0] = true;
 72     int head = 0,rear = 1;
 73     while(head<rear)
 74     {
 75         node u = queue[head];
 76         if((u.anum==c)||(u.bnum==c))
 77         {///得到目标状态
 78             int dept = u.deep;
 79             cout<<dept<<endl;
 80             for(int i=u.deep;i>0;i--)
 81             {
 82                 if(u.par == -1) break;
 83                 ans[i] = u.index;
 84                 u = queue[u.par];
 85             }
 86             for(int i=1;i<=dept;i++)
 87                 cout<<action[ans[i]]<<endl;
 88             return true;
 89         }
 90         for(int i=0;i<6;i++)///遍历6个入口
 91         {
 92             int ta,tb;
 93             change(u.anum,u.bnum,ta,tb,i);
 94             if(!visit[ta][tb])
 95             {///当前状态没有被访问过
 96                 queue[rear].anum = ta;
 97                 queue[rear].bnum = tb;
 98                 queue[rear].deep = u.deep+1;
 99                 queue[rear].index = i;
100                 queue[rear].par = head;
101                 visit[ta][tb] = true;
102                 rear++;
103             }
104         }
105         head++;
106     }
107     return false;
108 }
109 int main()
110 {
111     while(cin>>a>>b>>c)
112     {
113         memset(visit,false,sizeof(visit));
114         if(!bfs())
115             cout<<"impossible"<<endl;
116     }
117     return 0;
118 }

 

posted @ 2018-02-22 22:26  卉卉卉大爷  阅读(323)  评论(0编辑  收藏  举报