Pots POJ - 3414
考察:bfs
原思路:
在纸上模拟后,得出需要去重的结论.本来是利用pair存储,map去重顺便记录步数.但是这样没办法储存路径.后来想用map<pii,vector<string> > 存储经历的字符串.但是这样每次得到的新结点又会是新的vector,然后就卡此处没做出来
看大佬代码后思路:
用结构体存储a,b桶.在里面也记录步数且用字符串记录下标以记录半径.这里的操作用二维数组去重,是我完全没想到的
这里记录半径也可多种方法,比如上面的vector思路先赋值在压入字符串.
易错:
操作3不要写错了,我因此WA一次
1 #include <iostream> 2 #include <queue> 3 #include <cstdio> 4 #include <string> 5 using namespace std;//新判重思路:二维数组 6 struct node{ 7 int first,second,d; 8 string ans; 9 }; 10 string foot[10] = {"","FILL(1)","DROP(1)","POUR(1,2)","FILL(2)","DROP(2)","POUR(2,1)"}; 11 const int N = 110; 12 bool vis[N][N]; 13 int a,b,c; 14 node oper(int id,int i,node p)//第几个桶,第几个操作 15 { 16 if(i==1&&id==1) p.first = a; 17 else if(i==1&&id==2) p.second = b; 18 else if(i==2&&id==1) p.first = 0; 19 else if(i==2&&id==2) p.second = 0; 20 else if(i==3&&id==1){//把第一个桶的水倒入第二个 21 int tmp = p.second; 22 p.second = min(b,p.first+p.second); 23 p.first = max(p.first - p.second + tmp,0); 24 }else if(i==3&&id==2){ 25 int tmp = p.first; 26 p.first = min(a,p.first+p.second); 27 p.second = max(p.second - p.first + tmp,0); 28 } 29 return p; 30 } 31 void bfs(node st) 32 { 33 vis[0][0] = 1; 34 st.ans = ""; 35 st.first = st.second = st.d = 0; 36 queue<node> q; 37 q.push(st); 38 while(!q.empty()) 39 { 40 node it = q.front(); 41 q.pop(); 42 if(it.first==c||it.second==c){ 43 printf("%d\n",it.d); 44 for(int i=0;i<it.ans.size();i++) 45 printf("%s\n",foot[it.ans[i]-'0'].c_str()); 46 return; 47 } 48 for(int i=1,j=1;j<=2;i++){ 49 if(i==4) j++,i=1; 50 node tmp = oper(j,i,it); 51 if(!vis[tmp.first][tmp.second]) 52 { 53 // printf("%d,%d到%d,%d\n",it.first,it.second,tmp.first,tmp.second); 54 vis[tmp.first][tmp.second] = 1; 55 int idx = (j-1)*3+i; 56 char c = idx+'0'; 57 tmp.ans = it.ans+ c; 58 tmp.d = it.d+1; 59 q.push(tmp); 60 } 61 } 62 } 63 printf("impossible\n"); 64 return; 65 } 66 int main() 67 { 68 // freopen("in.txt","r",stdin); 69 scanf("%d%d%d",&a,&b,&c); 70 node st; 71 bfs(st); 72 return 0; 73 }