Pots(POJ-3414)【BFS】

题意:有两个有着固定容量的茶壶,初始时都为空,要求用FILL,POUR,DROP三种操作来准确地得到C值,输出最少次数及操作方案。

思路:比赛的时候真是脑子不好使,根本没想到是搜索,看了别人的题解用搜索,恍然大悟。

  以两茶壶均为空为初始状态,每次对六种操作进行枚举,BFS加记录路径即可。

代码如下:

Pots(POJ-3414)【BFS】
  1 #include<cstdio>
  2 #include<queue>
  3 #include<vector>
  4 using namespace std;
  5 struct water{
  6     int ta[3],steps;
  7     water(){}
  8     water(int x,int y,int z){
  9         ta[1]=x;ta[2]=y;
 10         steps=y;
 11     }
 12 };
 13 typedef pair<water,int> P;
 14 char op[6][15]={"FILL(1)\n","FILL(2)\n","DROP(1)\n","DROP(2)\n","POUR(1,2)\n","POUR(2,1)\n"};
 15 int a[3],c;
 16 
 17 P fill(water wt,int i){
 18     wt.steps++;
 19     if(wt.ta[i]<a[i])
 20     {
 21         wt.ta[i]=a[i];
 22         return P(wt,1);
 23     }
 24     return P(wt,0);
 25 }
 26 
 27 P drop(water wt,int i){
 28     wt.steps++;
 29     if(wt.ta[i]>0){
 30         wt.ta[i]=0;
 31         return P(wt,1);
 32     }
 33     return P(wt,0);
 34 }
 35 
 36 P pour(water wt,int i,int j){
 37     wt.steps++;
 38     if(wt.ta[i]==0||wt.ta[j]==a[j])
 39         return P(wt,0);
 40     int x=wt.ta[1]+wt.ta[2],y=0;
 41     if(x>a[j]){
 42         y=x-a[j];
 43         x=a[j];
 44     }
 45     wt.ta[i]=y;wt.ta[j]=x;
 46     return P(wt,1);
 47 }
 48 int main(){
 49     scanf("%d%d%d",&a[1],&a[2],&c);
 50     queue<water> q;
 51     q.push(water(0,0,0));
 52     int book[200][200]={1},ansFind=0;
 53     water pre[200][200],ending;
 54     while(!q.empty()){
 55         water wt=q.front();
 56         q.pop();
 57         if(wt.ta[1]==c||wt.ta[2]==c){
 58             ending=wt;
 59             ansFind=wt.steps;
 60             break;
 61         }
 62         for(int i=1;i<=2;i++){
 63             P ha=fill(wt,i);
 64             if(ha.second&&!book[ha.first.ta[1]][ha.first.ta[2]]){
 65                 book[ha.first.ta[1]][ha.first.ta[2]]=1;
 66                 q.push(ha.first);
 67                 pre[ha.first.ta[1]][ha.first.ta[2]]=wt;
 68                 pre[ha.first.ta[1]][ha.first.ta[2]].steps=i;
 69             }
 70         }
 71         for(int i=1;i<=2;i++){
 72             P ha=drop(wt,i);
 73             if(ha.second&&!book[ha.first.ta[1]][ha.first.ta[2]]){
 74                 book[ha.first.ta[1]][ha.first.ta[2]]=1;
 75                 q.push(ha.first);
 76                 pre[ha.first.ta[1]][ha.first.ta[2]]=wt;
 77                 pre[ha.first.ta[1]][ha.first.ta[2]].steps=i+2;
 78             }
 79         }
 80         for(int i=1;i<=2;i++){
 81             P ha=pour(wt,i,3-i);
 82             if(ha.second&&!book[ha.first.ta[1]][ha.first.ta[2]]){
 83                 book[ha.first.ta[1]][ha.first.ta[2]]=1;
 84                 q.push(ha.first);
 85                 pre[ha.first.ta[1]][ha.first.ta[2]]=wt;
 86                 pre[ha.first.ta[1]][ha.first.ta[2]].steps=i+4;
 87             }
 88         }
 89     }
 90     if(ansFind){
 91         vector<int> ans;
 92         water tmp=ending,start=water(0,0,0);
 93         printf("%d\n",ansFind);
 94         while((tmp.ta[1]+tmp.ta[2])!=0){
 95             tmp=pre[tmp.ta[1]][tmp.ta[2]];
 96             ans.push_back(tmp.steps);
 97         }
 98         for(int i=ans.size()-1;i>=0;i--){
 99             printf("%s",op[ans[i]-1]);
100         }
101     }
102     else printf("impossible");
103     return 0;
104 }
By xxmlala

 

上一篇:设备启动功能


下一篇:寸动功能