G - Pots
You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:
- 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).
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.
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).
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’.
3 5 4Sample 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 }

浙公网安备 33010602011771号