Fork me on GitHub

POJ - 3414 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 ≤ ≤ 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 AB, 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 }

 

posted @ 2020-06-16 21:39  shiyu-coder  阅读(108)  评论(0)    收藏  举报