POJ - 3414 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.
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)
这道题做起来可是不容易……因为一些未知的原因不停的WA,但是又不知道怎么了突然就AC了……
一个需要注意的地方就是这道题与棋盘类型的问题不一样,棋盘是标记走过的格子,而这道题是标记达到过的状态(两个容器的液体体积),
防止重复遍历某些情况
然后BFS就行了,记录操作这一块我是用一个deque记录的,直接记录的string,所以速度慢了一点,如果用int记录,后面转换回去会更快一点
1 #include<iostream> 2 #include<queue> 3 #include<deque> 4 #include<string> 5 #include<string.h> 6 #include<stdlib.h> 7 using namespace std; 8 9 const int max_num=3000; 10 11 struct Status{//记录某一时刻的状态 12 int liter[2]; //A和B容器目前含有的液体体积 13 }; 14 struct Choice{ 15 Status status; 16 deque<string> operation; 17 }; 18 19 int C=0; 20 int max_liter[2]; //A和B容器的最大液体体积 21 int pre_status[200][200]={0}; //记录到过的状态 22 queue<Choice> q; //BFS队列 23 deque<string> best_opera; //最佳策略 24 //deque<string> operation; 利用双端队列存储每次的操作 25 26 void BFS(Status status, deque<string> operation){ 27 Choice c; 28 c.status=status;c.operation=operation; 29 q.push(c); 30 pre_status[c.status.liter[0]][c.status.liter[1]]=1; 31 int num=0; 32 while(num<max_num){ 33 num++; 34 Choice ch=q.front(); 35 q.pop(); 36 pre_status[ch.status.liter[0]][ch.status.liter[1]]=1; 37 if(ch.status.liter[0]==C||ch.status.liter[1]==C){ 38 //成功得到体积C 39 best_opera=ch.operation; 40 break; 41 } 42 //Fill操作 43 for(int i=0;i<2;i++){ 44 if(ch.status.liter[i]==max_liter[i]){ 45 continue; 46 } 47 Status Sfill=ch.status; 48 Sfill.liter[i]=max_liter[i]; 49 if(pre_status[Sfill.liter[0]][Sfill.liter[1]]==1){ 50 continue; 51 } 52 deque<string> Ofill=ch.operation; 53 char number=i+1+'0'; 54 string line="FILL("; 55 line+=number; 56 line+=")"; 57 Ofill.push_back(line); 58 Choice fill;fill.status=Sfill;fill.operation=Ofill; 59 q.push(fill); 60 } 61 //Drop操作 62 for(int i=0;i<2;i++){ 63 if(ch.status.liter[i]==0){ 64 continue; 65 } 66 Status Sdrop=ch.status; 67 Sdrop.liter[i]=0; 68 if(pre_status[Sdrop.liter[0]][Sdrop.liter[1]]==1){ 69 continue; 70 } 71 deque<string> Odrop=ch.operation; 72 char number=i+1+'0'; 73 string line="DROP("; 74 line+=number; 75 line+=")"; 76 Odrop.push_back(line); 77 Choice drop;drop.status=Sdrop;drop.operation=Odrop; 78 q.push(drop); 79 } 80 //Pour操作 81 for(int i=0;i<2;i++){ 82 if(ch.status.liter[i]==0||ch.status.liter[1-i]==max_liter[1-i]){ 83 continue; 84 } 85 Status Spour=ch.status; 86 int sub=max_liter[1-i]-Spour.liter[1-i]; 87 if(sub>=Spour.liter[i]){ 88 Spour.liter[1-i]+=Spour.liter[i]; 89 Spour.liter[i]=0; 90 }else{ 91 Spour.liter[i]-=sub; 92 Spour.liter[1-i]=max_liter[1-i]; 93 } 94 if(pre_status[Spour.liter[0]][Spour.liter[1]]==1){ 95 continue; 96 } 97 deque<string> Opour=ch.operation; 98 char number1=i+1+'0',number2=2-i+'0'; 99 string line="POUR("; 100 line+=number1; 101 line+=",";line+=number2; 102 line+=")"; 103 Opour.push_back(line); 104 Choice pour;pour.status=Spour;pour.operation=Opour; 105 q.push(pour); 106 } 107 } 108 return; 109 110 } 111 112 int main(){ 113 cin >>max_liter[0]>>max_liter[1]>>C; 114 Status begin; 115 begin.liter[0]=0;begin.liter[1]=0; 116 deque<string> oper; 117 BFS(begin,oper); 118 if(best_opera.size()<=0){ 119 cout <<"impossible"<<endl; 120 }else{ 121 cout <<best_opera.size()<<endl; 122 for(int i=0;i<best_opera.size();i++){ 123 cout <<best_opera.at(i)<<endl; 124 } 125 } 126 127 system("pause"); 128 return 0; 129 }


浙公网安备 33010602011771号