G - Pots

You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

  1. FILL(i)        fill the pot i (1 ≤ i ≤ 2) from the tap;
  2. DROP(i)      empty the pot i to the drain;
  3. 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).

Write a program to find the shortest possible sequence of these operations that will yield exactly C liters of water in one of the pots.

Input

On the first and only line are the numbers A, B, and C. These are all integers in the range from 1 to 100 and C≤max(A,B).

Output

The first line of the output must contain the length of the sequence of operations K. The following K lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.

Sample Input
3 5 4
Sample Output
6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)



题目意思:给你两个罐子A和B,你可以进行六种操作,让你求得最少的步骤使得A或B的罐子容量为C
两个罐子都在变化于是当一个罐子变化时要更新另一个罐子的变化
  1 #include<iostream>
  2 #include<cstring>
  3 #include<queue>
  4 #include<stack>
  5 using namespace std;
  6 
  7 const int maxn=105;
  8 int a,b,c;
  9 typedef struct node1//node1表示罐子1,node2表示罐子2,step表示步数
 10 {
 11     int a;
 12     int b;
 13     int step;
 14 }node1;
 15 typedef struct node2
 16 {
 17     int i;//记录操作
 18     node2 *pre;//记录前驱结点
 19 }node2;
 20 
 21 bool visited[maxn][maxn];//标志数组,避免重复进行步骤,发生死循环。
 22 
 23 void print(int n)
 24 {
 25     if(n==0)
 26         cout<<"FILL(1)"<<endl;
 27     else if(n==1)
 28         cout<<"DROP(1)"<<endl;
 29     else if(n==2)
 30         cout<<"POUR(1,2)"<<endl;
 31     else if(n==3)
 32         cout<<"FILL(2)"<<endl;
 33     else if(n==4)
 34         cout<<"DROP(2)"<<endl;
 35     else
 36         cout<<"POUR(2,1)"<<endl;
 37 }
 38 int bfs(int a,int b,int c,node2 *p)
 39 {
 40     queue<node1> Q;
 41     node1 head,temp;
 42     head.a=head.b=head.step=0;
 43     visited[head.a][head.b]=true;
 44     Q.push(head);
 45     int s=0;
 46     int pre_s=-1;
 47     p[s].pre=NULL;
 48     int i;
 49     while(!Q.empty())
 50     {
 51         head=Q.front();
 52         Q.pop();
 53         pre_s++;
 54         for(i=0;i<6;i++)
 55         {
 56             temp.a=head.a;
 57             temp.b=head.b;
 58             temp.step=head.step;
 59             if(i==0)//第一步
 60             {
 61                 temp.a=a;//灌满罐子1
 62             }
 63             else if(i==1)
 64             {
 65                 temp.a=0;
 66             }
 67             else if(i==2)
 68             {
 69                 if(temp.a>=b-temp.b)//如果1罐子比2罐子剩下的容量多
 70                 {
 71                     temp.a=temp.a-b+temp.b;//1罐子向2 罐子倒水,1罐子只剩下剩下的水了
 72                     temp.b=b;//2罐子满脸
 73                 }
 74                 else
 75                 {
 76                     temp.b+=temp.a;//1罐子全部倒进2罐子
 77                     temp.a=0;//1罐子空了
 78                 }
 79             }
 80             else if(i==3)
 81             {
 82                 temp.b=b;
 83             }
 84             else if(i==4)
 85             {
 86                 temp.b=0;
 87             }
 88             else if(i==5)
 89             {
 90                 if(temp.b>=a-temp.a)//2罐子比1罐子剩下的容量多
 91                 {
 92                     temp.b=temp.b-a+temp.a;//先减后加否则会爆掉
 93                     temp.a=a;
 94                 }
 95                 else
 96                 {
 97                     temp.a+=temp.b;
 98                     temp.b=0;
 99                 }
100             }
101             if(!visited[temp.a][temp.b])
102             {
103                 s++;//操作数++
104                 p[s].i=i;
105                 p[s].pre=&p[pre_s];//指向前驱节点,保存前驱节点地址&取地址
106                 visited[temp.a][temp.b]=true;//标记
107                 temp.step+=1;//记录步长
108                 Q.push(temp);
109                 if(temp.a==c||temp.b==c)  //成功达到了 题目要求的数,接下来压栈
110                 {
111                     cout<<temp.step<<endl;
112                     stack<node2> S;
113                     node2 x=p[s];//临时保存p【s】
114                     while(x.pre!=NULL)
115                     {
116                         S.push(x);
117                         x=*(x.pre);//解开指针,取值
118                     }
119                     while(!S.empty())
120                     {
121                         x=S.top();
122                         S.pop();
123                         print(x.i);
124                     }
125                     return 0;
126                 }
127             }
128         }
129     }
130     cout<<"impossible"<<endl;
131     return 0;
132 }
133 int main()
134 {
135     while(cin>>a>>b>>c)
136     {
137         node2 p[10005];
138         memset(visited,false,sizeof(visited));
139         bfs(a,b,c,p);
140     }
141 }

 

posted @ 2020-11-12 20:54  BlackSnow  阅读(110)  评论(0)    收藏  举报