题意:有两个有着固定容量的茶壶,初始时都为空,要求用FILL,POUR,DROP三种操作来准确地得到C值,输出最少次数及操作方案。
思路:比赛的时候真是脑子不好使,根本没想到是搜索,看了别人的题解用搜索,恍然大悟。
以两茶壶均为空为初始状态,每次对六种操作进行枚举,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