cdoevs 1226 倒水问题
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description
有两个无刻度标志的水壶,分别可装 x 升和 y 升 ( x,y 为整数且均不大于 100 )的水。设另有一水 缸,可用来向水壶灌水或接从水壶中倒出的水, 两水壶间,水也可以相互倾倒。已知 x 升壶为空 壶, y 升壶为空壶。问如何通过倒水或灌水操作, 用最少步数能在x或y升的壶中量出 z ( z ≤ 100 )升的水 来。
输入描述 Input Description
一行,三个数据,分别表示 x,y 和 z;
输出描述 Output Description
一行,输出最小步数 ,如果无法达到目标,则输出"impossible"
样例输入 Sample Input
3 22 1
样例输出 Sample Output
14
1 /*注意是两个瓶子在一起才能表示一种状态,考虑好两个瓶子之间倒水的八种情况://向大壶倒满水 2 //向小壶倒满水 3 //大壶的水不要 4 //小壶的水不要 5 //大壶向小壶倒满水 6 //大壶向小壶倒水 ,倒不满 7 //小壶向大壶倒全部水,大壶没满 8 //小壶向大壶倒水,大壶满了 9 */ 10 #define N 120 11 #include<iostream> 12 using namespace std; 13 #include<cstdio> 14 bool visit[N][N]; 15 #include<queue> 16 int x,y,z; 17 struct node{ 18 int big,smal,sum; 19 }; 20 int bfs(int &ans) 21 { 22 visit[0][0]=true; 23 queue<node>que; 24 que.push(node{0,0,0}); 25 while(!que.empty()) 26 { 27 node now=que.front(); 28 que.pop(); 29 int a=now.big,b=now.smal,dep=now.sum; 30 if(a==z||b==z) 31 { 32 ans=dep; 33 return 0; 34 } 35 if(!visit[x][b]) 36 { 37 visit[x][b]=true; 38 que.push(node{x,b,dep+1}); 39 } 40 if(!visit[a][y]) 41 { 42 visit[a][y]=true; 43 que.push(node{a,y,dep+1}); 44 } 45 if(!visit[0][b]) 46 { 47 visit[0][b]=true; 48 que.push(node{0,b,dep+1}); 49 } 50 if(!visit[a][0]) 51 { 52 visit[a][0]=true; 53 que.push(node{a,0,dep+1}); 54 } 55 if(a>=(y-b)&&!visit[a-(y-b)][y]) 56 { 57 visit[a-(y-b)][y]=true; 58 que.push(node{a-(y-b),y,dep+1}); 59 } 60 if(a<y-b&&!visit[0][a+b]) 61 { 62 visit[0][a+b]=true; 63 que.push(node{0,a+b,dep+1}); 64 }if(b>=(x-a)&&!visit[x][b-(x-a)]) 65 { 66 visit[x][b-(x-a)]=true; 67 que.push(node{x,b-(x-a),dep+1}); 68 }if(b<(x-a)&&!visit[a+b][0]) 69 { 70 visit[a+b][0]=true; 71 que.push(node{a+b,0,dep+1}); 72 } 73 } 74 } 75 int main() 76 { 77 int ans=0; 78 scanf("%d%d%d",&x,&y,&z); 79 if(x<y) swap(x,y); 80 bfs(ans); 81 if(ans) printf("%d ",ans); 82 else printf("impossible "); 83 return 0; 84 }