非常可乐(杭州电子科技大学第四届大学生程序设计竞赛)(九度2013年教程87题)

题目描述: 大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升(正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
输入: 三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
输出: 如果能平分的话请输出最少要倒的次数,否则输出"NO"。
样例输入: 7 4 3 4 1 3 0 0 0
样例输出: NO 3 提示:可参考教程.附下载地址

http://120.192.83.81/2/file.data.vdisk.me/49948774/f0c8e4bdf58b1a80a08cbc6d675580df763b1c55?ip=1361548192,111.15.172.124&ssig=T8hG%2BSRbkr&Expires=1361546992&KID=sae,l30zoo1wmz&fn=%E3%80%8A2013%E5%B9%B4%E7%8E%8B%E9%81%93%E8%AE%BA%E5%9D%9B%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%80%83%E7%A0%94%E6%9C%BA%E8%AF%95%E6%8C%87%E5%8D%97%E3%80%8B_20130112.pdf

#include <cstdio>
 #include <queue>
 using namespace std;
 
 bool mar[101][101][101];
 int S, N, M;
 struct Sta {
     int a, b, c, t;
     void init(int x, int y, int z, int cost) {
         a = x;
         b = y;
         c = z;
         t = cost;
     }
     void mark() {
         mar[a][b][c] = true;
     }
 };
 Sta tt, st;
 queue<Sta> Q;
 bool AtoB(int a, int &sa, int b, int &sb) {
     if (b - sb >= sa) {
         sb += sa;
         sa = 0;
     } else {
         sa -= b - sb;
         sb = b;
     }
     if ((tt.a == S / 2 && tt.b == S / 2) || (tt.a == S / 2 && tt.c == S / 2) || (tt.b == S / 2 && tt.c == S / 2))
         return true;
     else {
         if (!mar[tt.a][tt.b][tt.c]) {
             tt.t++;
             tt.mark();
             Q.push(tt);
         }
     }
     return false;
 }
 
 int bfs() {
     while (!Q.empty()) {
         st = Q.front();
         Q.pop();
         tt = st;
         if (AtoB(S, tt.a, N, tt.b)) 
             return tt.t + 1;
         tt = st;
         if (AtoB(S, tt.a, M, tt.c))
             return tt.t + 1;
         tt = st;
         if (AtoB(N, tt.b, S, tt.a))
             return tt.t + 1;
         tt = st;
         if (AtoB(N, tt.b, M, tt.c))
             return tt.t + 1;
         tt = st;
         if (AtoB(M, tt.c, S, tt.a))
             return tt.t + 1;
         tt = st;
         if (AtoB(M, tt.c, N, tt.b))
             return tt.t + 1;
     }
     return -1;
 }
 
 int main() {
     while (~scanf("%d%d%d", &S, &N, &M) && !(S == 0 && N == 0 && M == 0)) {
         if (S % 2 == 1) {
             printf("NO\n");
             continue;
         }
         for (int i = 0; i <= S; i++)
             for (int j = 0; j <= S; j++)
                 for (int k = 0; k <= S; k++)
                     mar[i][j][k] = false;
         while (!Q.empty())
             Q.pop();
         tt.init(S, 0, 0, 0);
         tt.mark();
         Q.push(tt);
         int time = bfs();
         if (time == -1)
             printf("NO\n");
         else
             printf("%d\n", time);
     }
     return 0;
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值