1. 程式人生 > >HDU1495 非常可樂 BFS

HDU1495 非常可樂 BFS

                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 Input7 4 34 1 30 0 0
Sample OutputNO3

思路:將所有狀態進行一次廣搜即可,程式碼雖長,但基本都是複製貼上

#include <string.h>#include <stdio.h>#include <queue>using namespace std;int s,n,m;int vis[105][105][105];struct node{    int s,n,m,step;};int
check(int x,int y,int z)//平分條件
{    if(x == 0 && y == z)        return 1;    if(y == 0 && x == z)        return 1;    if(z == 0 && x == y)        return 1;    return 0;}int bfs(){    queue<node> Q;    node a,next;    a.s = s;    a.n = 0;    a.m = 0;    a.step = 0;    vis[s][0][0] = 1
;    Q.push(a);    while(!Q.empty())    {        a = Q.front();        Q.pop();        if(check(a.s,a.n,a.m))            return a.step;        if(a.n)//當n杯中還有        {            if(a.n>s-a.s)//將n杯倒入s杯中能將s杯倒滿            {                next = a;                next.n = next.n-(s-a.s);                next.s = s;                if
(!vis[next.s][next.n][next.m])                {                    next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }            else//將n杯倒入s杯中不能將s杯倒滿            {                next = a;                next.s = next.n+next.s;                next.n = 0;                if(!vis[next.s][next.n][next.m])                {                    next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }            if(a.n>m-a.m)//將n杯倒入m杯中能將m杯倒滿            {                next = a;                next.n = next.n-(m-a.m);                next.m =  m;                if(!vis[next.s][next.n][next.m])                {                    next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }            else//將n杯倒入m杯中不能將m杯倒滿            {                next = a;                next.m = next.n+next.m;                next.n = 0;                if(!vis[next.s][next.n][next.m])                {                    next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }        }        if(a.m)//同上        {            if(a.m>s-a.s)            {                next = a;                next.m = next.m-(s-a.s);                next.s = s;                if(!vis[next.s][next.n][next.m])                {                    next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }            else            {                next = a;                next.s = next.m+next.s;                next.m = 0;                if(!vis[next.s][next.n][next.m])                {                    next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }            if(a.m>n-a.n)            {                next = a;                next.m = next.m-(n-a.n);                next.n =  n;                if(!vis[next.s][next.n][next.m])                {                    next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }            else            {                next = a;                next.n = next.m+next.n;                next.m = 0;                if(!vis[next.s][next.n][next.m])                {                    next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }        }        if(a.s)//同上        {            if(a.s>n-a.n)            {                next = a;                next.s = next.s-(n-a.n);                next.n = n;                if(!vis[next.s][next.n][next.m])                {                    next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }            else            {                next = a;                next.n = next.s+next.n;                next.s = 0;                if(!vis[next.s][next.n][next.m])                {                    next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }            if(a.s>m-a.m)            {                next = a;                next.s = next.s-(m-a.m);                next.m =  m;                if(!vis[next.s][next.n][next.m])                {                   next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }            else            {                next = a;                next.m = next.m+next.s;                next.s = 0;                if(!vis[next.s][next.n][next.m])                {                    next.step = a.step+1;                    Q.push(next);                    vis[next.s][next.n][next.m] = 1;                }            }        }    }    return 0;}int main(){    int ans;    while(~scanf("%d%d%d",&s,&n,&m),s||n||m)    {        if(s%2)//奇數肯定不能平分,因為被子是整數體積大小        {            printf("NO\n");            continue;        }        memset(vis,0,sizeof(vis));        ans = bfs();        if(ans)            printf("%d\n",ans);        else            printf("NO\n");    }    return 0;}