题目链接:http://poj.org/problem?id=3414
很有趣的题目。
每次六种决策,下面注释中已说明。
用string记录路径。
用二维vis数组记录两个杯子的状态,避免重复。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 #include<string> 7 using namespace std; 8 char *st[6]={"FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"}; 9 int vis[110][110]; //用二维数组记录两个杯子的状态 10 string s; 11 struct node 12 { 13 int a,b; 14 string s; //记录路径 15 16 }now,nex; 17 18 int ca,cb,cc; 19 20 string bfs() 21 { 22 queue<node> q; 23 now.a=0; 24 now.b=0; 25 now.s=""; 26 q.push(now); 27 vis[0][0]=1; 28 while(!q.empty()) 29 { 30 now=q.front(); 31 q.pop(); 32 if(now.a==cc||now.b==cc) return now.s; 33 if(now.a<ca&&!vis[ca][now.b]) //a加满 34 { 35 vis[ca][now.b]=1; 36 nex.a=ca; 37 nex.b=now.b; 38 nex.s=""; 39 nex.s=now.s+'0'; 40 q.push(nex); 41 42 } 43 if(now.b<cb&&!vis[now.a][cb]) //b加满 44 { 45 vis[now.a][cb]=1; 46 nex.a=now.a; 47 nex.b=cb; 48 nex.s=""; 49 nex.s=now.s+'1'; 50 q.push(nex); 51 } 52 if(now.a>0&&!vis[0][now.b]) //a倒掉 53 { 54 vis[0][now.b]=1; 55 nex.a=0; 56 nex.b=now.b; 57 nex.s=""; 58 nex.s=now.s+'2'; 59 q.push(nex); 60 } 61 if(now.b>0&&!vis[now.a][0]) //b倒掉 62 { 63 vis[now.a][0]=1; 64 nex.a=now.a; 65 nex.b=0; 66 nex.s=""; 67 nex.s=now.s+'3'; 68 q.push(nex); 69 } 70 if(now.a>0&&now.b<cb) //a倒给b 71 { 72 int v=min(now.a,cb-now.b); 73 nex.a=now.a-v; 74 nex.b=now.b+v; 75 if(!vis[nex.a][nex.b]) 76 { 77 vis[nex.a][nex.b]=1; 78 nex.s=""; 79 nex.s=now.s+'4'; 80 q.push(nex); 81 } 82 } 83 if(now.b>0&&now.a<ca) //b倒给a 84 { 85 int v=min(now.b,ca-now.a); 86 nex.a=now.a+v; 87 nex.b=now.b-v; 88 if(!vis[nex.a][nex.b]) 89 { 90 vis[nex.a][nex.b]=1; 91 nex.s=""; 92 nex.s=now.s+'5'; 93 q.push(nex); 94 } 95 } 96 97 } 98 return ""; 99 100 } 101 102 int main() 103 { 104 while(scanf("%d%d%d",&ca,&cb,&cc)!=EOF) 105 { 106 memset(vis,0,sizeof(vis)); 107 string s1 =bfs(); 108 if(s1.length()) 109 { 110 printf("%d ",s1.length()); 111 int len=s1.length(); 112 for(int i=0;i<len;i++) 113 printf("%s ",st[s1[i]-'0']); 114 } 115 else puts("impossible"); 116 } 117 }