您的位置:首页 > 其它

HDU1495-非常可乐-BFS

2015-08-31 20:16 399 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1495

题意:三个瓶子,容量为s,a,b,且s装满饮料 s=a+b

求至少倒多少下能使得某两个瓶子装着相同多的饮料。这是个模拟搜索BFS。想清楚总共就只有六种操作就行了。

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#define LL long long
#define inf 1<<29
#define s(a) scanf("%d",&a)
#define CL(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=105;
int n,s,a,b,c;
struct node{int dp[3],step;};
bool vis

;
queue<node>q;
void flag(node &f)
{
    f.step++;
    q.push(f);
    vis[f.dp[0]][f.dp[1]][f.dp[2]]=true;
}
int bfs(int s,int a,int b)
{
    CL(vis,false);
    while(!q.empty()) q.pop();
    node f,f_tmp;
    f.step=0;
    f.dp[0]=s;
    f.dp[1]=0;
    f.dp[2]=0;
    q.push(f);
    while(!q.empty()){
        f=q.front();q.pop();
        if(f.dp[0]==s/2&&(f.dp[1]==s/2||f.dp[2]==s/2)) return f.step;
        if(f.dp[1]==s/2&&f.dp[2]==s/2) return f.step;
        f_tmp=f;    //  第一种操作方法,1->2
        if(f.dp[0]>0&&f.dp[1]<a){
            if(f.dp[0]>=(a-f.dp[1])){
                f.dp[0]-=(a-f.dp[1]);
                f.dp[1]=a;
            }else{
                f.dp[1]+=f.dp[0];
                f.dp[0]=0;
            }
            if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f);
        }
        f=f_tmp;    //  第二种操作方法,1->3
        if(f.dp[0]>0&&f.dp[2]<b){
            if(f.dp[0]>=(b-f.dp[2])){
                f.dp[0]-=(b-f.dp[2]);
                f.dp[2]=b;
            }else{
                f.dp[2]+=f.dp[0];
                f.dp[0]=0;
            }
            if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f);
        }
        f=f_tmp;    //  第三种操作方法,2->1
        if(f.dp[1]>0&&f.dp[0]<s){
            if(f.dp[1]>=(s-f.dp[0])){
                f.dp[1]-=(s-f.dp[0]);
                f.dp[0]=s;
            }else{
                f.dp[0]+=f.dp[1];
                f.dp[1]=0;
            }
            if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f);
        }
        f=f_tmp;    //  第四种操作方法,2->3
        if(f.dp[1]>0&&f.dp[2]<b){
            if(f.dp[1]>=(b-f.dp[2])){
                f.dp[1]-=(b-f.dp[2]);
                f.dp[2]=b;
            }else{
                f.dp[2]+=f.dp[1];
                f.dp[1]=0;
            }
            if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f);
        }
        f=f_tmp;    //  第五种操作方法,3->1
        if(f.dp[2]>0&&f.dp[0]<s){
            if(f.dp[2]>=(s-f.dp[0])){
                f.dp[2]-=(s-f.dp[0]);
                f.dp[0]=s;
            }else{
                f.dp[0]+=f.dp[2];
                f.dp[2]=0;
            }
            if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f);
        }
        f=f_tmp;    //  第六种操作方法,3->2
        if(f.dp[2]>0&&f.dp[1]<a){
            if(f.dp[2]>=(a-f.dp[1])){
                f.dp[2]-=(a-f.dp[1]);
                f.dp[1]=a;
            }else{
                f.dp[1]+=f.dp[2];
                f.dp[2]=0;
            }
            if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f);
        }
    }
    return -1;
}
int main()
{
    while(~scanf("%d%d%d",&s,&a,&b)){
        if(!s&&!a&&!b) break;
        if(s&1) printf("NO\n");
        else{
            int k=bfs(s,a,b);
            if(k==-1) printf("NO\n");
            else printf("%d\n",k);
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: