题目:
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是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
思路:
实质上是有向图上求最短路,只需要模拟加记忆化即可。
Code:
1 #include<bits/stdc++.h> 2 using namespace std; 3 bool vis[100][100][100]; 4 5 typedef struct{ 6 int a; 7 int b; 8 int c; 9 int cnt; 10 }node; 11 12 bool ok(int a, int b, int c){ 13 if (a == b && !c) return true; 14 if (a == c && !b) return true; 15 if (b == c && !a) return true; 16 return false; 17 } 18 19 int bfs(int S, int N, int M){ 20 queue<node> q; 21 node s = {S, 0, 0, 0}; 22 q.push(s); 23 vis[S][0][0] = 1; 24 int ans = 0; 25 while(!q.empty()){ 26 s = q.front(); 27 q.pop(); 28 if (ok(s.a, s.b, s.c)) return s.cnt; 29 int na, nb, nc; 30 if (s.a){ 31 if (s.a > N-s.b){na = s.a-(N-s.b); nb = N; nc = s.c;} 32 else {na = 0; nb = s.a+s.b; nc = s.c;} 33 if (!vis[na][nb][nc]){ 34 node ns = {na, nb, nc, s.cnt+1}; q.push(ns); 35 vis[na][nb][nc] = 1; 36 } 37 if (s.a > M-s.c){na = s.a-(M-s.c); nc = M; nb = s.b;} 38 else {na = 0; nc = s.a+s.c; nb = s.b;} 39 if (!vis[na][nb][nc]){ 40 node nns = {na, nb, nc, s.cnt+1}; q.push(nns); 41 vis[na][nb][nc] = 1; 42 } 43 } 44 if (s.b){ 45 if (s.b > M-s.c){na = s.a; nb = s.b-(M-s.c); nc = M;} 46 else {na = s.a; nb = 0; nc = s.c+s.b;} 47 if (!vis[na][nb][nc]){ 48 node ns = {na, nb, nc, s.cnt+1}; q.push(ns); 49 vis[na][nb][nc] = 1; 50 } 51 na = s.a+s.b; nb = 0; nc = s.c; 52 if (!vis[na][nb][nc]){ 53 node nns = {na, nb, nc, s.cnt+1}; q.push(nns); 54 vis[na][nb][nc] = 1; 55 } 56 } 57 if (s.c){ 58 if (s.c > N-s.b){na = s.a; nc = s.c-(N-s.b); nb = N;} 59 else {na = s.a; nc = 0; nb = s.b+s.c;} 60 if (!vis[na][nb][nc]){ 61 node ns = {na, nb, nc, s.cnt+1}; q.push(ns); 62 vis[na][nb][nc] = 1; 63 } 64 na = s.a+s.c; nc = 0; nb = s.b; 65 if (!vis[na][nb][nc]){ 66 node nns = {na, nb, nc, s.cnt+1}; q.push(nns); 67 vis[na][nb][nc] = 1; 68 } 69 } 70 } 71 return 0; 72 } 73 74 int main() 75 { 76 int S, N, M; 77 while(scanf("%d%d%d", &S, &N, &M), S || N || M){ 78 memset(vis, 0, sizeof(vis)); 79 int ans = 0; 80 if (S % 2 == 0) ans = bfs(S, N, M); 81 if (ans) printf("%d\n", ans); 82 else printf("NO\n"); 83 } 84 85 return 0; 86 }