非常可乐(多参数bfs模拟
非常可乐 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 27624 Accepted Submission(s): 10740 Problem Description 大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。 Input 三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。 Output 如果能平分的话请输出最少要倒的次数,否则输出"NO"。
最后肯定是在瓶子和大杯子里平分,bfs结束条件是 m==half&&s==half,输入时就把M换成大杯子,之前纠结了很久。。。
情况很多种,细心些写
注: bfs时每个瓶子的子状态都要注意得到,之前只继承了倒水那两个另一个杯子忘继承父状态了,结果水越倒越少
#include<cstdio> #include<queue> #include<cstring> using namespace std; queue <int> q; int half; bool pass[150][150][150]; int S,M,N,vs[10000],vm[10000],vn[10000],step[10000]; void q_emp(){ while(!q.empty())q.pop(); } int bfs(){ int cnt=0; q.push(0); while(!q.empty()){ int t=q.front(); q.pop(); int s=vs[t],m=vm[t],n=vn[t],ans=step[t]; if(s==half&&m==half){ q_emp(); return ans; } int qs=S-s,qm=M-m,qn=N-n; if(s>0&& qm){ //printf("here1\n"); if(s>qm){ if(!pass[s-qm][M][n]){ pass[s-qm][M][n]=true; cnt++; vs[cnt]=s-qm; vm[cnt]=M; vn[cnt]=n; //之前忘写这句了。。。 step[cnt]=ans+1; q.push(cnt); } } else if(!pass[0][m+s][n]){ pass[0][m+s][n]=true; cnt++; vs[cnt]=0; vm[cnt]=m+s; vn[cnt]=n; step[cnt]=ans+1; q.push(cnt); } // printf("%d %d %d\n",vs[cnt],vm[cnt],vn[cnt]); } if(s>0&& qn){// printf("here2\n"); if(s>qn){ if(!pass[s-qn][m][N]){ pass[s-qn][m][N]=true; cnt++; vs[cnt]=s-qn; vn[cnt]=N; vm[cnt]=m; step[cnt]=ans+1; q.push(cnt); } } else if(!pass[0][m][s+n]){ pass[0][m][s+n]=true; cnt++; vs[cnt]=0; vn[cnt]=n+s; vm[cnt]=m; step[cnt]=ans+1; q.push(cnt); } // printf("%d %d %d\n",vs[cnt],vm[cnt],vn[cnt]); } if(m>0&& qn){// printf("here3\n"); if(m>qn){ if(!pass[s][m-qn][N]){ pass[s][m-qn][N]=true; cnt++; vm[cnt]=m-qn; vn[cnt]=N; vs[cnt]=s; step[cnt]=ans+1; q.push(cnt); } } else if(!pass[s][0][m+n]){ pass[s][0][m+n]=true; cnt++; vm[cnt]=0; vn[cnt]=n+m; vs[cnt]=s; step[cnt]=ans+1; q.push(cnt); } // printf("%d %d %d\n",vs[cnt],vm[cnt],vn[cnt]); } if(m>0&& qs){// printf("here4\n"); if(m>qs){ if(!pass[S][m-qs][n]){ pass[S][m-qs][n]=true; cnt++; vm[cnt]=m-qs; vs[cnt]=S; vn[cnt]=n; step[cnt]=ans+1; q.push(cnt); } } else if(!pass[s+m][0][n]){ pass[s+m][0][n]=true; cnt++; vm[cnt]=0; vs[cnt]=s+m; vn[cnt]=n; step[cnt]=ans+1; q.push(cnt); } // printf("%d %d %d\n",vs[cnt],vm[cnt],vn[cnt]); } if(n>0&& qm){// printf("here5\n"); if(n>qm){ if(!pass[s][M][n-qm]){ pass[s][M][n-qm]=true; cnt++; vm[cnt]=M; vn[cnt]=n-qm; vs[cnt]=s; step[cnt]=ans+1; q.push(cnt); } } else if(!pass[s][m+n][0]){ pass[s][m+n][0]=true; cnt++; vm[cnt]=m+n; vn[cnt]=0; vs[cnt]=s; step[cnt]=ans+1; q.push(cnt); }// printf("%d %d %d\n",vs[cnt],vm[cnt],vn[cnt]); } if(n>0&& qs){// printf("here6\n"); if(n>qs){ if(!pass[S][m][n-qs]){ pass[S][m][n-qs]=true; cnt++; vn[cnt]=n-qs; vs[cnt]=S; vm[cnt]=m; step[cnt]=ans+1; q.push(cnt); } } else if(!pass[s+n][m][0]){ pass[s+n][m][0]=true; cnt++; vn[cnt]=0; vs[cnt]=s+n; vm[cnt]=m; step[cnt]=ans+1; q.push(cnt); }// printf("%d %d %d\n",vs[cnt],vm[cnt],vn[cnt]); } } return -1; } int main(){ int ans; while(scanf("%d%d%d",&S,&M,&N)&&S){ if(N>M){int t=M; M=N; N=t;} memset(pass,false,sizeof(pass)); vs[0]=S; vm[0]=0; vn[0]=0; step[0]=0; if(S%2!=0)printf("NO\n"); else{ if(M==N){printf("1\n");continue;} half=S/2; ans=bfs(); if(ans<0)printf("NO\n"); else printf("%d\n",ans); } } return 0; }