1. 程式人生 > >非常可樂(多參數bfs模擬

非常可樂(多參數bfs模擬

printf div des space cst accep pri esc output

非常可樂
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; }

非常可樂(多參數bfs模擬