1. 程式人生 > 實用技巧 >非常可樂

非常可樂

大家一定覺的運動以後喝可樂是一件很愜意的事情,但是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<bits/stdc++.h>
using namespace std;
int a[3];
int half,vis[101][101][101];
struct node
 {
     int arr[3];
     int step;
 }p,tmp;
 void bfs()
 {
     queue<node> que;
     p.arr[
0]=a[0]; p.arr[1]=p.arr[2]=p.step=0;//p記錄了狀態 que.push(p); while(!que.empty()) { p=que.front(); que.pop(); for(int i=0;i<3;i++) { if(p.arr[i]>0) for(int j=0;j<3;j++) { tmp=p;
if(i==j)//一個杯子不可能既接水又倒水 continue; if(tmp.arr[i]>a[j]-tmp.arr[j])//能裝滿杯子 {//j向i倒水 tmp.arr[i]=tmp.arr[i]-(a[j]-tmp.arr[j]);//i剩下的水 tmp.arr[j]=a[j];//arr【j】滿了 } else//不能倒滿 { tmp.arr[j]
+=tmp.arr[i]; tmp.arr[i]=0; } if(!vis[tmp.arr[0]][tmp.arr[1]][tmp.arr[2]])//判斷是否出現過 { vis[tmp.arr[0]][tmp.arr[1]][tmp.arr[2]]=1; tmp.step++; if((tmp.arr[0]==half&&tmp.arr[1]==half)||(tmp.arr[0]==half&&tmp.arr[2]==half)||(tmp.arr[1]==half&&tmp.arr[2]==half)) { cout<<tmp.step<<endl; return ; } que.push(tmp); } } } } cout<<"NO"<<endl; } int main() { while(cin>>a[0]>>a[1]>>a[2]&&(a[0]!=0)&&(a[1]!=0)&&a[2]!=0) { memset(vis,0,sizeof(vis)); if(a[0]%2)//奇數一定不能平分 cout<<"NO"<<endl; else { half=a[0]>>1; bfs(); } } return 0; }