非常可乐(多参数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;
}
posted @ 2019-02-23 14:10  易如鱼  阅读(262)  评论(0编辑  收藏  举报