HDU1495:非常可乐
kuangbin专题一:M题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 17203 Accepted Submission(s): 6970
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"。
Sample Input
7 4 3 4 1 3 0 0 0
Sample Output
NO 3
思路:广度优先搜索
AC代码 两种姿势
/*题目很水 应该不需要注释吧...... 推荐列举 六种操作情况 虽然代码量大 但是可以 copy 当然数组循环操作也是可以的 代码量小就是 理解起来稍微麻烦点 */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <queue> using namespace std ; #define maxn 120 struct node { int x , y , z ; int step ; }; node st ; int s , n , m ; bool visit[maxn][maxn][maxn] ; void BFS(){ queue<node>Q ; Q.push(st) ; memset(visit , 0 , sizeof(visit)) ; visit[0][0][s] = 1 ; while(!Q.empty()){ node q = Q.front() ; Q.pop() ; node turn ; if( (q.x == s/2 && q.y == s/2 ) || (q.x==s/2 && q.z==s/2) || (q.z==s/2 && q.y==s/2)){ printf("%d\n" , q.step) ; return; } int min_num ; min_num = min(q.x , m-q.y) ; turn.x = q.x - min_num ; turn.y = q.y + min_num ; turn.z = q.z ; turn.step = q.step + 1 ; if(!visit[turn.x][turn.y][turn.z]){ visit[turn.x][turn.y][turn.z] = 1 ; Q.push(turn) ; } min_num = min(q.x , s - q.z) ; turn.x = q.x - min_num ; turn.y = q.y ; turn.z = q.z + min_num ; turn.step = q.step + 1 ; if(!visit[turn.x][turn.y][turn.z]){ visit[turn.x][turn.y][turn.z] = 1 ; Q.push(turn) ; } min_num = min(q.y , n - q.x) ; turn.x = q.x + min_num ; turn.y = q.y - min_num ; turn.z = q.z ; turn.step = q.step + 1 ; if(!visit[turn.x][turn.y][turn.z]){ visit[turn.x][turn.y][turn.z] = 1 ; Q.push(turn) ; } min_num = min(q.y , s - q.z) ; turn.x = q.x ; turn.y = q.y - min_num ; turn.z = q.z + min_num ; turn.step = q.step + 1 ; if(!visit[turn.x][turn.y][turn.z]){ visit[turn.x][turn.y][turn.z] = 1 ; Q.push(turn) ; } min_num = min(n-q.x , q.z) ; turn.x = q.x + min_num ; turn.y = q.y ; turn.z = q.z - min_num ; turn.step = q.step + 1 ; if(!visit[turn.x][turn.y][turn.z]){ visit[turn.x][turn.y][turn.z] = 1 ; Q.push(turn) ; } min_num = min(m-q.y , q.z) ; turn.x = q.x ; turn.y = q.y + min_num ; turn.z = q.z - min_num ; turn.step = q.step + 1 ; if(!visit[turn.x][turn.y][turn.z]){ visit[turn.x][turn.y][turn.z] = 1 ; Q.push(turn) ; } } printf("NO\n") ; return; } int main(){ while(~scanf("%d%d%d" , &s , &n , &m)){ if(s==0 && n==0 && m==0 ){ break ; } if(s % 2 == 1 ){ printf("NO\n") ; } else { st.x = 0 ; st.y = 0 ; st.z = s ; st.step = 0 ; BFS() ; } } return 0 ; }
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<queue> using namespace std; int visit[300][300]; int f[3]; struct state { int x[3]; int step;//倒的次数; }; queue<state>s; void bfs() { int i,j; state p; p.x[0]=f[0]; p.x[1]=0; p.x[2]=0; p.step=0; s.push(p); while(!s.empty()) { state q; q=s.front(); s.pop(); if((q.x[0]==f[0]/2&&q.x[1]==f[0]/2)||(q.x[0]==f[0]/2&&q.x[2]==f[0]/2)||(q.x[2]==f[0]/2&&q.x[1]==f[0]/2))//判断是否满足条件 { printf("%d\n",q.step); return; } for(i=0;i<=2;i++) { state y; if(q.x[i]>0)//将i的可乐倒入j中 { for(j=0;j<=2;j++) { if(i==j) continue; if(q.x[i]+q.x[j]>f[j]) { y.x[i]=q.x[i]-(f[j]-q.x[j]); y.x[j]=f[j]; y.x[3-i-j]=q.x[3-i-j]; } else { y.x[i]=0; y.x[j]=q.x[i]+q.x[j]; y.x[3-i-j]=q.x[3-i-j]; } int a,b; a=y.x[1]; b=y.x[2]; if(a>=0&&b>=0&&a<=f[1]&&b<=f[2]&&visit[a][b]==0) { visit[a][b]=1; y.step=q.step+1; s.push(y); } } } } } printf("NO\n"); } int main() { while(scanf("%d%d%d",&f[0],&f[1],&f[2])!=EOF&&(f[0]||f[1]||f[2])) { if(f[0]%2) { printf("NO\n"); continue; } if(f[1]==f[2]) { printf("1\n"); continue; } else { while(!s.empty()) s.pop(); memset(visit,0,sizeof(visit)); visit[0][0]=true; bfs(); } } return 0; }