非常可乐
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17358 Accepted Submission(s): 7042
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广度优先搜索,六种情况,判断好往哪里倒,倒的时候又有哪些情况就可以,最后如果两个相等,另一个是零,才是平分,这里判断改了好多次。。。。。#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; int n,m,s;//代表了三个瓶子的容量 int vis[120][120][120];//标记三个瓶子的状态是否出现过 struct node{ int n,m,s;//记录每一次瓶子中可乐的状态 int step;//记录倒可乐的次数 }rounds,nextrounds; void Bfs(){//用广度优先搜索 queue<node>q; int i; memset(vis,0,sizeof(vis)); q.push(rounds); vis[rounds.s][rounds.n][rounds.m] = 1; while(!q.empty()){ rounds = q.front(); //printf("s:%d n:%d m:%d\n",rounds.s,rounds.n,rounds.m); if((rounds.s==rounds.n&&rounds.m==0)||(rounds.s==rounds.m&&rounds.n==0)||(rounds.m==rounds.n&&rounds.s==0)){//平分,输出次数,返回,注意相等时不能为0,否则一开始0,0程序就结束了 printf("%d\n",rounds.step);//上面的判断改了很多次,一是一开始两个杯子都是0,是相等的但是不行,所以相等但不为零,二是及时相等相加必须为总数,否则样例1就不会输出no了 return; } q.pop(); for(i = 0; i < 6; i++){//6中情况s->n,n->s,s->m,m->s,n->m,m->n;重点 if(i==0){//s->n if((n-rounds.n)>=rounds.s){//如果n中所剩空间大于等于s中的可乐,就可以把s中的可乐全部倒在n中 nextrounds.n = rounds.n + rounds.s;//原有的加上s中的 nextrounds.s = 0;//全部倒在n中了 nextrounds.m = rounds.m;//另一个瓶子不变 nextrounds.step = rounds.step + 1;//次数加一 } else{//如果n所剩空间小于s中的可乐量,则把n倒满,s还剩下一部分 nextrounds.n = n;//n倒满了 nextrounds.s = rounds.s-(n-rounds.n);//s中剩下部分为原来s减去n中没装满的那一部分 nextrounds.m = rounds.m;//不变 nextrounds.step = rounds.step + 1;//次数加1 } if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){ q.push(nextrounds); vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1; } } else if(i==1){//n->s if((s-rounds.s)>=rounds.n){//s中所剩空间大于n的可乐量,可以把n中倒完 nextrounds.s = rounds.s + rounds.n; nextrounds.n = 0; nextrounds.m = rounds.m; nextrounds.step = rounds.step + 1; } else{//s中所剩空间小于n中可乐量,可以把s倒满,n中剩余 nextrounds.s = s; nextrounds.n = rounds.n - (s-rounds.s); nextrounds.m = rounds.m; nextrounds.step = rounds.step + 1; } if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){ q.push(nextrounds); vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1; } } else if(i==2){//s->m if((m-rounds.m)>=rounds.s){//m中剩余空间大于s可乐量,s倒完 nextrounds.m = rounds.m + rounds.s; nextrounds.s = 0; nextrounds.n = rounds.n; nextrounds.step = rounds.step + 1; } else{//m剩余空间小于s可乐量,m倒满,s剩余 nextrounds.m = m; nextrounds.s = rounds.s - (m-rounds.m); nextrounds.n = rounds.n; nextrounds.step = rounds.step + 1; } if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){ q.push(nextrounds); vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1; } } else if(i==3){//m->s if((s-rounds.s)>=rounds.m){//s中剩余空间大于m可乐量,m倒完 nextrounds.s = rounds.m + rounds.s; nextrounds.m = 0; nextrounds.n = rounds.n; nextrounds.step = rounds.step + 1; } else{//s剩余空间小于m可乐量,s倒满,m剩余 nextrounds.s = s; nextrounds.m = rounds.m - (s-rounds.s); nextrounds.n = rounds.n; nextrounds.step = rounds.step + 1; } if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){ q.push(nextrounds); vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1; } } else if(i==4){//n->m; if((m-rounds.m)>=rounds.n){//m中剩余空间大于n可乐量,n倒完 nextrounds.m = rounds.m + rounds.n; nextrounds.n = 0; nextrounds.s = rounds.s; nextrounds.step = rounds.step + 1; } else{//m剩余空间小于n可乐量,m倒满,n剩余 nextrounds.m = m; nextrounds.n = rounds.n - (m-rounds.m); nextrounds.s = rounds.s; nextrounds.step = rounds.step + 1; } if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){ q.push(nextrounds); vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1; } } else{//m->n if((n-rounds.n)>=rounds.m){//n中剩余空间大于m可乐量,m倒完 nextrounds.n = rounds.n + rounds.m; nextrounds.m = 0; nextrounds.s = rounds.s; nextrounds.step = rounds.step + 1; } else{//n剩余空间小于m可乐量,n倒满,m剩余 nextrounds.n = n; nextrounds.m = rounds.m - (n-rounds.n); nextrounds.s = rounds.s; nextrounds.step = rounds.step + 1; } if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){ q.push(nextrounds); vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1; } } } } printf("NO\n");//如果队列为空了说明方法都用完了,不可能平分 return; } int main(){ int i; while(~scanf("%d%d%d",&s,&n,&m)){ if(s==0&&n==0&&m==0)break; rounds.s = s; rounds.n = 0; rounds.m = 0; rounds.step = 0; if(s%2){//奇数肯定不能平分 printf("NO\n"); } else{ Bfs(); } } return 0; }