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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章