1. 程式人生 > 實用技巧 >HDU - 1495 非常可樂

HDU - 1495 非常可樂

連結 http://acm.hdu.edu.cn/showproblem.php?pid=1495

題目描述

大家一定覺的運動以後喝可樂是一件很愜意的事情,但是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"結束。

樣例輸入

7 4 3
4 1 3
0 0 0

樣例輸出

NO
3

直接bfs模擬就好了
有六個轉移方向,當然我們可以保持a,b,c是遞減的
這樣更好操作

#include<iostream>
#include<algorithm>
#include<queue>
#include<unordered_set>
using namespace std;

constexpr int N = 0x3f3f3f3f;
int ans = 0x3f3f3f3f;

unordered_set<int> used;
struct Node{
    int x,y,z;
    int res=0;
    Node(){
        x=y=z=0;
    }
    Node(int _x, int _y, int _z, int _res=0):x(_x), y(_y), z(_z), res(_res){};
};

int main(){
    // freopen("in.dat", "r", stdin);
    auto get = [](int x, int y, int z){
        return x*1000000+y*1000+z;
    };
    int a, b , c;
    cin>>a>>b>>c;
    while (a&&b&&c)
    {
        if(b<c) swap(b,c);//保證第二個最大
        if(b==c){
            cout<<1;
            cout<<endl;
            cin>>a>>b>>c;
            continue;
        }
        queue<Node> que;
        ans = 0x3f3f3f3f;
        que.push(Node(a,0,0));
        used.clear();
        used.insert(get(a,0,0));
        int temp;
        while (!que.empty())
        {
            auto e=que.front();
            que.pop();
            if(e.z==0&&e.x==e.y){  //最後兩個肯定在大的裡面
                ans = e.res;
                break;
            }
            temp= min(e.x+e.y, b);
            if(used.find(get(e.x+e.y-temp, temp, e.z))==used.end()) //可以從a裡面倒進去
            {
                used.insert(get(e.x+e.y-temp, temp, e.z));
                que.push(Node(e.x+e.y-temp, temp, e.z, e.res+1));
            }
            temp= min(e.x+e.z, c);
            if(used.find(get(e.x+e.z-temp, e.y, temp))==used.end()){
                used.insert(get(e.x+e.z-temp, e.y, temp));
                que.push(Node(e.x+e.z-temp, e.y, temp, e.res+1));
            }
            temp= min(e.y+e.z, c);
            if(used.find(get(e.x, e.y+e.z-temp, temp))==used.end()){
                used.insert(get(e.x, e.y+e.z-temp, temp));
                que.push(Node(e.x, e.y+e.z-temp, temp, e.res+1));
            }
            if(used.find(get(e.x+e.y, 0, e.z))==used.end()){
                 used.insert(get(e.x+e.y, 0, e.z));
                que.push(Node(e.x+e.y, 0, e.z, e.res+1));
            }
            if(used.find(get(e.x+e.z, e.y, 0))==used.end()){
                used.insert(get(e.x+e.z, e.y, 0));
                que.push(Node(e.x+e.z, e.y, 0, e.res+1));
            }
            int temp = min(e.y+e.z, b);
            if(used.find(get(e.x, temp, e.y+e.z-temp))==used.end()){
                used.insert(get(e.x, temp, e.y+e.z-temp));
                que.push(Node(e.x, temp, e.y+e.z-temp));
            }
        }
        if(ans==N)
            cout<<"NO";
        else
            cout<<ans;
        cout<<endl;
        cin>>a>>b>>c;
    }
    return 0;
}