HDU
来源:互联网 发布:网络通信协议是如何被 编辑:程序博客网 时间:2024/06/05 09:09
思路:bfs。倒水共有6中情况既(A->B,A->C),(B->A,B->C),(C->A,C->B),我们可以写一个双重循环来模拟这六种情况(当然你也可以把这六种情况一一写出来)。当 i -> j,i给j倒水的时候有两种情况,① i 可以把 j 给装满 ② i 装不满 j 。两种情况不一样记得判断一下即可。标记数组开为3维,每一个维度表示一个杯子。
注意:结束条件为严格的有两个杯子中有S/2的水(比如对于样例二,2 1 1不算结束,必须的2 0 2才可以),且判断条件不能写成S/2,因为7/3 == 2会出错。
#include<bits/stdc++.h>using namespace std;int S[5];struct Node{ int cup[3],step;}NOW, NEXT;bool vis[105][105][105];int bfs(){ memset(vis, 0, sizeof(vis)); queue<Node> q; NOW.cup[0] = S[0]; NOW.cup[1] = 0; NOW.cup[2] = 0; NOW.step = 0; vis[S[0]][0][0] = true; q.push(NOW); while (!q.empty()) { NOW = q.front(); q.pop(); if ((NOW.cup[0] * 2 == S[0] && NOW.cup[1] * 2 == S[0]) || (NOW.cup[0] * 2 == S[0] && NOW.cup[2] * 2 == S[0]) || (NOW.cup[1] * 2 == S[0] && NOW.cup[2] * 2 == S[0])) { return NOW.step; } for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (i != j) { NEXT = NOW; if (NOW.cup[i] >= S[j] - NOW.cup[j])//i能倒满j { NEXT.cup[i] = NOW.cup[i] - (S[j] - NOW.cup[j]); NEXT.cup[j] = S[j]; } else { NEXT.cup[i] = 0; NEXT.cup[j] = NOW.cup[i] + NOW.cup[j]; } NEXT.step = NOW.step + 1; if (!vis[NEXT.cup[0]][NEXT.cup[1]][NEXT.cup[2]]) { vis[NEXT.cup[0]][NEXT.cup[1]][NEXT.cup[2]] = true; q.push(NEXT); } } } } } return -1;}int main(){ while (~scanf("%d%d%d",&S[0], &S[1], &S[2]) && (S[0] + S[1] + S[2])) { int ans = bfs(); if (ans != -1) printf("%d\n",ans); else printf("NO\n"); } return 0;}/*7 4 34 1 30 0 0*/
阅读全文