题意:
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
分析:直接搜索+模拟
对于N和M俩个杯子的当前状态,每次都有俩种选择,S->N,S->M,N->S,N->M,M->S,M->N
用了BFS和DFS 个写了一个,写dfs的时候,开了个全局Debug了半天,ORZ
BFS版
#include<iostream> #include<algorithm> #include<queue> using namespace std; bool vis[110][110]; short S,N,M,s,n,m; int ans; struct state { short n,m; short cnt; state(short a=0,short b=0,short c=0):n(a),m(b),cnt(c){} }; queue<state> Q; void BFS() { Q.push(state(0,0,0)); vis[0][0]=true; state tmp; while(!Q.empty()) { tmp=Q.front(); Q.pop(); if((tmp.n==S/2 || tmp.m==S/2)&&(S-(tmp.n+tmp.m))==S/2) { ans=tmp.cnt; return ; } s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m; if(s!=0) { if(s+n>=N) { s-=(N-n); n=N; } else { n+=s; s=0; } if(!vis[n][S-s-n]){ Q.push(state(n,S-s-n,tmp.cnt+1)); vis[n][S-s-n]=true; } s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m; if(s+m>=M) { s-=(M-m); m=M; } else m+=s,s=0; if(!vis[S-s-m][m]){ Q.push(state(S-s-m,m,tmp.cnt+1)); vis[S-s-m][m]=true; } } s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m; if(n!=0) { if(!vis[0][m]){ Q.push(state(0,m,tmp.cnt+1)); vis[0][m]=true; } if(n+m>=M) { n-=(M-m); m=M; } else m+=n,n=0; if(!vis[n][m]){ Q.push(state(n,m,tmp.cnt+1)); vis[n][m]=true; } } s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m; if(m!=0) { if(!vis[n][0]){ Q.push(state(n,0,tmp.cnt+1)); vis[n][0]=true; } if(m+n>=N) { m-=(N-n); n=N; } else n+=m,m=0; if(!vis[n][m]){ Q.push(state(n,m,tmp.cnt+1)); vis[n][m]=true; } } } } int main() { while(scanf("%d %d %d",&S,&N,&M)==3 && (S||N||M)) { if(S%2!=0) { puts("NO"); continue; } memset(vis,false ,sizeof(vis)); while(!Q.empty()) Q.pop(); ans=-1; BFS(); if(ans==-1) puts("NO"); else printf("%d\n",ans); } }
DFS版
#include<iostream> const int inf=0x7fffffff; const int MAX=105; using namespace std; int ans; int S,N,M; bool vis[MAX][MAX]; void dfs(int a,int b,int cnt) { // cout<<"check"<<vis[0][3]<<endl; if((a==S/2||b==S/2) && (S-(a+b))==S/2) { // cout<<a<<' '<<b<<endl; if(ans>cnt) ans=cnt; return ; } int s=S-a-b,n=a,m=b; if(s!=0) { if(s+n>=N) { s-=(N-n); n=N; } else n+=s,s=0; if(!vis[n][m]){ vis[n][m]=1; // cout<<"S->n"<<endl; dfs(n,m,cnt+1); vis[n][m]=0; // cout<<"fan1 "<<n<<' '<<m<<' '<<vis[n][m]<<endl; } s=S-a-b,n=a,m=b; if(s+m>=M) { s-=(M-m); m=M; } else m+=s,s=0; // printf("%d %d\n",n,m); // cout<<cnt<<endl; // cout<<vis[n][m]<<endl; if(!vis[n][m]){ vis[n][m]=1; // cout<<"S->m"<<endl; dfs(n,m,cnt+1); vis[n][m]=0; // cout<<"fan2 "<<n<<' '<<m<<' '<<vis[n][m]<<endl; } } s=S-a-b,n=a,m=b; if(n!=0) { if(!vis[0][m]){ vis[0][m]=1; // cout<<"N->S"<<endl; dfs(0,m,cnt+1); vis[0][m]=0; // cout<<"fan3 "<<0<<' '<<m<<' '<<vis[0][m]<<endl; } if(n+m>=M) { n-=(M-m); m=M; } else m+=n,n=0; if(!vis[n][m]){ vis[n][m]=1; // cout<<"N->m"<<endl; dfs(n,m,cnt+1); vis[n][m]=0; // cout<<"fan4 "<<n<<' '<<m<<' '<<vis[n][m]<<endl; } } s=S-a-b,n=a,m=b; if(m!=0) { if(!vis[n][0]){ vis[n][0]=1; // cout<<"m->s"<<endl; dfs(n,0,cnt+1); vis[n][0]=0; // cout<<"fan5 "<<n<<' '<<m<<' '<<vis[n][0]<<endl; } if(m+n>=N) { m-=(N-n); n=N; } else n+=m,m=0; if(!vis[n][m]){ vis[n][m]=1; // cout<<"m->n"<<endl; dfs(n,m,cnt+1); vis[n][m]=0; // cout<<"fan6 "<<n<<' '<<m<<' '<<vis[n][m]<<endl; } } } int main(void) { while(scanf("%d %d %d",&S,&N,&M)==3&& (S||N||M)) { if(S%2!=0) { puts("NO"); continue; } memset(vis,0,sizeof(vis)); ans=inf; vis[0][0]=1; dfs(0,0,0); if(ans==inf) puts("NO"); else printf("%d\n",ans); } return 0; }
这是PKU上面一道类似的题目的代码,不同的是,这题目要求保存路径
#include<iostream> #include<algorithm> #include<string> #include<queue> using namespace std; struct state { int a,b; string road; state(int x=0,int y=0,string str=""):a(x),b(y),road(str){} }; //A : drop A //B : drop B //C : A to B //D : B to A //E : fill A //F " fill B queue<state> Q; int vis[101][101],A,B,C; bool success; string ans; void BFS() { success=false; Q.push(state(0,0,"")); memset(vis,false,sizeof(vis)); vis[0][0]=true; while(!Q.empty()) { state temp=Q.front(); string str=temp.road; Q.pop(); int a=temp.a,b=temp.b,a1,b1; if(a==C || b==C) { success=true; ans=temp.road; return ; } if(a!=0 && !vis[0][b]) { vis[0][b]=true; Q.push(state(0,b,(str + "A"))); } if(b!=0 && !vis[a][0]) { vis[a][0]=true; Q.push(state(a,0,(str + "B"))); } if(a!=0 && b!=B) { if(a+b<B) { b1=a+b; a1=0; } else { b1=B; a1=a+b-B; } if(!vis[a1][b1]) { vis[a1][b1]=true; Q.push(state(a1,b1,(str+"C"))); } } if(a!=A && b!=0) { if(a+b<A) { a1=a+b; b1=0; } else a1=A,b1=a+b-A; if(!vis[a1][b1]) { vis[a1][b1]=true; Q.push(state(a1,b1,(str+"D"))); } } if(a!=A && !vis[A][b]) { vis[A][b]=true; Q.push(state(A,b,(str+"E"))); } if(b!=B && !vis[a][B]) { vis[a][B]=true; Q.push(state(a,B,(str+"F"))); } } } int main() { while(scanf("%d %d %d",&A,&B,&C)==3) { while(!Q.empty()) Q.pop(); BFS(); if(!success) { puts("impossible"); continue; } //cout<<ans<<endl; int len=ans.length(); printf("%d\n",len); for(int i=0;i<len;i++) { if(ans[i]=='A') puts("DROP(1)"); else if(ans[i]=='B') puts("DROP(2)"); else if(ans[i]=='C') puts("POUR(1,2)"); else if(ans[i]=='D') puts("POUR(2,1)"); else if(ans[i]=='E') puts("FILL(1)"); else puts("FILL(2)"); } } return 0; }