码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1495 非常可乐(bfs)

时间:2017-08-13 15:08:59      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:std   return   cst   include   space   自己   color   scan   str   

题意:已知S是装满可乐的可乐瓶体积, N和M是两个无刻度空杯子的容量,S=N+M,问能否通过若干次转移,使可乐平分。

输入:三个整数S N M,多组数据,以0 0 0结尾。

输出:如果能平分的话请输出最少要倒的次数,否则输出"NO"。

限制:101>S>0,N>0,M>0

注:本题可以用gcd的数论做法,效率高,但bfs更直接,此处选择bfs解法。

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int v[5];//记录S N M容量 
bool sign[105][105][105];//sign记录bfs中3个水杯容藏可乐情况
struct cup{
    int v[5],step;//记录该状态3个水杯容藏可乐的量以及步数 
}temp;
void pour(int a,int b){//倒水函数,把a杯子中的可乐倒到b杯子中
    int sum=temp.v[a]+temp.v[b];
    temp.v[b]=min(sum,v[b]);
    temp.v[a]=sum-temp.v[b];
}
void bfs(){
    queue<cup>q;
    cup cnt;
    cnt.v[1]=v[1],cnt.v[2]=cnt.v[3]=cnt.step=0;
    q.push(cnt);
    memset(sign,0,sizeof(sign));
    sign[v[1]][0][0]=true;
    while(!q.empty()){
        cnt=q.front();q.pop();
        if(cnt.v[1]==cnt.v[3]&&cnt.v[2]==0){printf("%d\n",cnt.step);return;}//结束条件 
        for(int i=1;i<=3;i++)
        for(int j=1;j<=3;j++){
            if(i!=j){//不能自己倒水给自己  
                temp=cnt;//每个水位情况都要把所有操作枚举一遍,所以都要赋值为原始水位情况  
                pour(i,j);
                if(!sign[temp.v[1]][temp.v[2]][temp.v[3]]){
                    sign[temp.v[1]][temp.v[2]][temp.v[3]]=true;
                    temp.step++;
                    q.push(temp);
                }
            }
        }
    }
    puts("NO");
}
int main(){
    while(scanf("%d%d%d",&v[1],&v[2],&v[3]),v[1]){
        if(v[1]%2){puts("NO");continue;}//若S为奇数,不可能平分 
        if(v[2]>v[3]) swap(v[2],v[3]);
        bfs();
    }
    return 0;
}

 

HDU 1495 非常可乐(bfs)

标签:std   return   cst   include   space   自己   color   scan   str   

原文地址:http://www.cnblogs.com/fushang/p/7353401.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!