HDU 1495 非常可乐 (kuangbin带你飞 专题一:简单搜索)

六种倒可乐情况...m到n或s,n倒m或s,s倒n或m...每一种倒法都有两种:倒满了或者没倒满...应该不算是难题,不过就是不好写...写的满令人崩溃的...去hdu交这个题目的时候发现以前A过了,看了一下好像是看的讨论版的规律...真是惭愧...

BFS写法:

#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
int used[105][105];//判断两个杯子装可乐的情况是否出现过
struct node
{
    int m,n,s,t;
};
int m,n,s;
int bfs()
{
    queue<node> q;
    node  now,next;
    now.m=now.n=now.t=0;
    now.s=s;
    q.push(now);
    memset(used,0,sizeof(used));
    used[0][0]=1;
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        if(now.n==now.s&&now.s==s/2)
            return now.t;
        if(now.m+now.s>m)  //s->m
        {
            next.m=m,next.n=now.n,next.s=now.m+now.s-m,next.t=now.t+1;
            if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
        else
        {
            next.m=now.m+now.s,next.n=now.n,next.s=0,next.t=now.t;
             if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
        if(now.n+now.s>n)  //s->n
        {
            next.m=now.m,next.n=n,next.s=now.n+now.s-n,next.t=now.t+1;
            if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
        else
        {
            next.m=now.m,next.n=now.n+now.s,next.s=0,next.t=now.t+1;
            if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
        if(now.m+now.n>n)  //m->n
        {
            next.m=now.m+now.n-n,next.n=n,next.s=now.s,next.t=now.t+1;
            if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
        else
        {
            next.m=0,next.n=now.n+now.m,next.s=now.s,next.t=now.t+1;
            if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
        if(now.m+now.s>s)  //m->s
        {
            next.m=now.m+now.s-s,next.n=now.n,next.s=s,next.t=now.t+1;
            if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
        else
        {
            next.m=0,next.n=now.n,next.s=now.m+now.s,next.t=now.t+1;
            if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
        if(now.n+now.m>m)  //n->m
        {
            next.m=m,next.n=now.n+now.m-m,next.s=now.s,next.t=now.t+1;
            if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
        else
        {
            next.m=now.n+now.m,next.n=0,next.s=now.s,next.t=now.t+1;
            if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
        if(now.n+now.s>s) //n->s
        {
            next.m=now.m,next.n=now.n+now.s-s,next.s=s,next.t=now.t+1;
            if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
        else
        {
            next.m=now.m,next.n=0,next.s=now.n+now.s,next.t=now.t+1;
            if(used[next.m][next.n]==0)
            {
                used[next.m][next.n]=1;
                q.push(next);
            }
        }
    }
    return -1;
}
int main()
{
    while(cin>>s>>n>>m,n+m+s)
    {
        if(s%2)
            printf("NO\n");
        else
        {
            if(n<m) swap(n,m);
            int ans=bfs();
            if(ans==-1)
                printf("NO\n");
            else
                printf("%d\n",ans);
        }
    }
    return 0;
}

规律写法:

#include <cstdio>

int gcd(int x, int y)
{
    return y ? gcd(y, x % y) : x;
}

int main()
{
    int a, b, c;
    
    while (scanf("%i%i%i", &a, &b, &c), a + b + c) {
        (a /= gcd(b, c)) & 1 && ~puts("NO") || printf("%i\n", a - 1);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值