搜索专题(BFS)HDU 1495-非常可乐

来源:互联网 发布:单片机主程序流程图 编辑:程序博客网 时间:2024/06/05 15:36

题目链接:

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

思路分析:

因为涉及到求最少次数,所以第一感觉是用BFS模拟倒可乐,设得到三个杯子中可乐分别记为a,b,c,可以用一个mark数组查重,因为通过不同的方式得到相同的abc时,只要取步数最少的那种即可。结束条件的判断需要注意,一开始我以为只要使一个杯子中可乐为1/2S即可,后来发现要把另外两份倒在一起才算平分完。

这道题我最开始犯了一个错误,我以为a,b,c可以为小数,后来才发现题目说了要为整数,这样一来,如果可乐为奇数的话可以直接输出NO了。还是要看清楚题目对数据的限制条件才是啊。

后来百度这道题发现还可以用数论知识解决,(orz,我还没接触过数论的题)。

数论解法链接:http://blog.csdn.net/v5zsq/article/details/52097459

代码实现:

#include"cstdio"#include"queue"#include"map"#include"cstring"using namespace std;int S,N,M;int mark[105][105];int aczc(int&p,int&q,int ma){    if(p==0||q==ma)        return 0;    if(p>=ma-q)    {        p=p-(ma-q);        q=ma;    }    else    {        q=p+q;        p=0;    }    return 1;}int BFS(int cnt,int x,int y,int z){    memset(mark,-1,sizeof(mark));    typedef pair<int,int>p;    typedef pair<p,p>P;    queue<P>que;    que.push(P(p(x,y),p(z,cnt)));    while(!que.empty())    {        int a,b,c;        x=que.front().first.first;        y=que.front().first.second;        z=que.front().second.first;        cnt=que.front().second.second;        que.pop();        //结束条件:两个杯子为S/2        if(x==S/2&&(y==0||z==0)||y==S/2&&(x==0||z==0)||z==S/2&&(x==0||y==0))        {            //printf("a%d b%d c%d cnt%d\n",x,y,z,cnt);            return cnt;        }        a=x;b=y;c=z;        if(aczc(a,b,N)&&mark[a][b]==-1)        {            que.push(P(p(a,b),p(c,cnt+1)));            mark[a][b]=c;        }        a=x;b=y;c=z;        if(aczc(a,c,M)&&mark[a][b]==-1)        {            que.push(P(p(a,b),p(c,cnt+1)));            mark[a][b]=c;        }        a=x;b=y;c=z;        if(aczc(b,a,S)&&mark[a][b]==-1)        {            que.push(P(p(a,b),p(c,cnt+1)));            mark[a][b]=c;        }        a=x;b=y;c=z;        if(aczc(b,c,M)&&mark[a][b]==-1)        {            que.push(P(p(a,b),p(c,cnt+1)));            mark[a][b]=c;        }        a=x;b=y;c=z;        if(aczc(c,a,S)&&mark[a][b]==-1)        {            que.push(P(p(a,b),p(c,cnt+1)));            mark[a][b]=c;        }        a=x;b=y;c=z;        if(aczc(c,b,N)&&mark[a][b]==-1)        {            que.push(P(p(a,b),p(c,cnt+1)));            mark[a][b]=c;        }    }    return 0;}int main(){    while(1)    {        scanf("%d%d%d",&S,&N,&M);        if(S==0&&N==0&&M==0)            break;        if(S%2!=0)        {            printf("NO\n");            continue;        }        int x=BFS(0,S,0,0);        if(x)            printf("%d\n",x);        else printf("NO\n");    }    return 0;}


0 0
原创粉丝点击