HDU1495:非常可乐(BFS)

非常可乐
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 27010 Accepted Submission(s): 10487

Problem Description
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是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

总结经验:以后可以把所有情况枚举出来的就用bfs。

这道题互相倒来倒去总共有6种情况,比如说三个容器名就叫s,n,m:

  1. s -> n
  2. s -> m
  3. n -> s
  4. n -> m
  5. m -> s
  6. m -> n

然后就把所有情况用if枚举出来的咯,比如说要看是不是第一种情况,那判断的条件就是s里面有可乐,n还没倒满,其中还要分两种情况,1.s足够把n倒满。2.s还不能够把n倒满。 以此类推其他5种情况。

判断的条件是两个容器里面的可乐相等,并且这两个容器里的可乐加起来就为总的可乐容量(s)。

若队列空了,还没有返回步数,那就说明平分不了,返回-1,所以是在while循环外面写上return -1;

下面附上ac代码:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <ctype.h>
#include <queue>
#include <cmath>
#define INF 0x3f3f3f3f
#define mod 1000000007
using namespace std;
typedef long long int ll;
int s,n,m;
int sgn[105][105][105];
struct node {
    int s,n,m,step;
};
bool check(int s,int n,int m) { //判断是否已经“走过”这种状态
    if(sgn[s][n][m] == 1) {
        return false;
    }
    return true;
}
bool succeed(int ss,int nn,int mm) { //判断是否已经平分
    if(ss == nn && ss + nn == s) { //****这里不能写mm == 0 !
        return true;                 //7 4 3 -> 7 0 0 ->4 4 3  DENIED
    } else if(ss == mm && ss + mm == s) {
        return true;
    } else if(nn == mm && nn + mm == s) {
        return true;
    } else {
        return false;
    }
}
int bfs() {
    memset(sgn,0,sizeof(sgn)); //初始化为0
    node cur,next;
    cur.s = s;
    cur.n = 0; //** 注意:一开始n和m两个杯子还没有可乐
    cur.m = 0; //**
    sgn[s][0][0] = 1; //标记这种情况已经"走过"了 是s 0 0 !不是s n m!
    cur.step = 0;
    queue<node>q;
    q.push(cur);
    while(!q.empty()) {
        cur = q.front();
        q.pop();
        if(succeed(cur.s,cur.n,cur.m)) {
            return cur.step;
        }
        if(cur.s > 0 && cur.n < n) { //互相倒一共有6种情况  //1
            if(cur.s > n - cur.n) {
                next.s = cur.s - (n - cur.n);
                next.n = n;
                next.m = cur.m;  //是cur.m!  不是m!
            } else {
                next.s = 0;
                next.n = cur.n + cur.s;
                next.m = cur.m;
            }
            if(check(next.s,next.n,next.m)) {
                sgn[next.s][next.n][next.m] = 1;
                next.step = cur.step + 1;
                q.push(next);
            }
        }
        if(cur.s > 0 && cur.m < m) { // 2
            if(cur.s > m - cur.m) {
                next.s = cur.s - (m - cur.m);
                next.n = cur.n;
                next.m = m;
            } else {
                next.s = 0;
                next.n = cur.n;
                next.m = cur.m + cur.s;
            }
            if(check(next.s,next.n,next.m)) {
                sgn[next.s][next.n][next.m] = 1;
                next.step = cur.step + 1;
                q.push(next);
            }
        }
        if(cur.n > 0 && cur.s < s) {  // 3
            if(cur.n > s - cur.s) {
                next.s = s;
                next.n = cur.n - (s - cur.s);
                next.m = cur.m;
            } else {
                next.s = cur.s + cur.n;
                next.n = 0;
                next.m = cur.m;
            }
            if(check(next.s,next.n,next.m)) {
                sgn[next.s][next.n][next.m] = 1;
                next.step = cur.step + 1;
                q.push(next);
            }
        }
        if(cur.n > 0 && cur.m < m) { // 4
            if(cur.n > m - cur.m) {
                next.s = cur.s;
                next.n = cur.n - (m - cur.m);
                next.m = m;
            } else {
                next.s = cur.s;
                next.n = 0;
                next.m = cur.m + cur.n;
            }
            if(check(next.s,next.n,next.m)) {
                sgn[next.s][next.n][next.m] = 1;
                next.step = cur.step + 1;
                q.push(next);
            }
        }
        if(cur.m > 0 && cur.s < s) { // 5
            if(cur.m > s - cur.s) {
                next.s = s;
                next.n = cur.n;
                next.m = cur.m - (s - cur.s);
            } else {
                next.s = cur.s + cur.m;
                next.n = cur.n;
                next.m = 0;
            }
            if(check(next.s,next.n,next.m)) {
                sgn[next.s][next.n][next.m] = 1;
                next.step = cur.step + 1;
                q.push(next);
            }
        }
        if(cur.m > 0 && cur.n < n) { // 6
            if(cur.m > n - cur.n) {
                next.s = cur.s;
                next.n = n;
                next.m = cur.m - (n - cur.n);
            } else {
                next.s = cur.s;
                next.n = cur.n + cur.m;
                next.m = 0;
            }
            if(check(next.s,next.n,next.m)) {
                sgn[next.s][next.n][next.m] = 1;
                next.step = cur.step + 1;
                q.push(next);
            }
        }
    }
    return -1;
}
int main() {
    while(cin >> s >> n >> m) {
        if(s == 0 && n == 0 && m == 0) {
            break;
        }
        if(bfs() == -1) {cout << "NO" << endl;}
        else {cout << bfs() << endl;}
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43555854/article/details/86649767