POJ 3414 Pots(算法随手记:这个广搜可还行)

8 篇文章 0 订阅

题目链接:http://poj.org/problem?id=3414

这是在bin巨的专题里面看到的题目,以前不知所措,现在能勉强凑合,能比划两下,写下来给更多的人看看,希望会有用

题目大意是说,我们有两个杯子,水有无限多个,我们可以有三种操作,问的是,最后能不能让水杯中的水的容量达到某个值,我们的操作是,从两个杯子都是空的这个状态开始,搜寻它能够达到的状态,然后一直进行状态转移,一直到满足题意的状态出现,我们结束程序,如果这个状态不存在,我们就输出“impossible”

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
struct edge
{
    int k1;
    int k2;
    int op;
    int step;
    int pre;
    int cop;
};
int a, b, c, last, visit[150][150];
edge copy1[1000000];
void bfs(void);
int main(void)
{
    scanf("%d %d %d", &a, &b, &c);
    for(int i = 0; i< 100; i++)
    {
        for(int j = 0; j < 100; j++)
        {
            visit[i][j] = 0;
        }
    }
    bfs();
    int nn = copy1[last].step;
    int a[1000];
    if(nn == 0)
    {
        printf("impossible\n");
        return 0;
    }
    for(int i = (nn-1); i >= 0; i--)
    {
        a[i] = copy1[last].op;
        last = copy1[last].pre;
    }
    printf("%d\n", nn);
    for(int i = 0; i < nn; i++)
    {
        if(a[i] == 0)
        {
            printf("FILL(1)\n");
        }
        else if(a[i] == 1)
        {
            printf("FILL(2)\n");
        }
        else if(a[i] == 2)
        {
            printf("DROP(1)\n");
        }
        else if(a[i] == 3)
        {
            printf("DROP(2)\n");
        }
        else if(a[i] == 4)
        {
            printf("POUR(1,2)\n");
        }
        else
        {
            printf("POUR(2,1)\n");
        }
    }
    return 0;
}
void bfs(void)
{
    queue<edge> map;
    edge k;
    k.k1 = 0;
    k.k2 = 0;
    k.pre = 0;
    k.step = 0;
    k.cop = 0;
    int copi = 0;
    copy1[copi] = k;
    map.push(k);
    visit[0][0] = 1;
    while(!map.empty())
    {
        edge now  = map.front();
        map.pop();
        if((now.k1 == c) || (now.k2 == c))
        {
            last = now.cop;
            return ;
        }
        int local = now.cop;
        for(int i = 0; i < 6; i++)
        {
            edge next;
            if(i == 0) //把第一个瓶子装满 
            {
                next.k1 = a;
                next.k2 = now.k2;
                next.pre = local;
                next.step = now.step + 1;
                next.op = 0;
                if(!visit[next.k1][next.k2])
                {
                    copi++;
                    next.cop = copi;
                    copy1[copi] = next;
                    map.push(next);
                    visit[next.k1][next.k2] = 1;
                }
            }
            if(i == 1) //把第二个瓶子装满 
            {
                next.k2 = b;
                next.k1 = now.k1;
                next.pre = local;
                next.step = now.step + 1;
                next.op = 1;
                if(!visit[next.k1][next.k2])
                {
                    copi++;
                    next.cop = copi;
                    copy1[copi] = next;
                    map.push(next);
                    visit[next.k1][next.k2] = 1;
                }
            }
            if(i == 2) //把第一个瓶子倒掉 
            {
                next.k1 = 0;
                next.k2 = now.k2;
                next.pre = local;
                next.step = now.step + 1;
                next.op = 2;
                if(!visit[next.k1][next.k2])
                {
                    copi++;
                    next.cop = copi;
                    copy1[copi] = next;
                    map.push(next);
                    visit[next.k1][next.k2] = 1;
                }
            }
            if(i == 3) //把第二个瓶子倒掉 
            {
                next.k2 = 0;
                next.k1 = now.k1;
                next.pre = local;
                next.step = now.step + 1;
                next.op = 3;
                if(!visit[next.k1][next.k2])
                {
                    copi++;
                    next.cop = copi;
                    copy1[copi] = next;
                    map.push(next);
                    visit[next.k1][next.k2] = 1;
                }
            }
            if(i == 4) //第一个瓶子给第二个瓶子倒水 
            {
                if(b - now.k2 < now.k1)
                {
                    next.k1 = now.k1 - (b-now.k2);
                    next.k2 = b;
                }
                else
                {
                    next.k1 = 0;
                    next.k2 = now.k2 + now.k1;
                }
                next.pre = local;
                next.step = now.step + 1;
                next.op = 4;
                if(!visit[next.k1][next.k2])
                {
                    copi++;
                    next.cop = copi;
                    copy1[copi] = next;
                    map.push(next);
                    visit[next.k1][next.k2] = 1;
                }
            }
            if(i == 5) //第二个瓶子给第一个瓶子倒水 
            {
                if(a - now.k1 < now.k2)
                {
                    next.k2 = now.k2 - (a-now.k1);
                    next.k1 = a;
                }
                else
                {
                    next.k2 = 0;
                    next.k1 = now.k1 + now.k2;
                }
                next.pre = local;
                next.step = now.step + 1;
                next.op = 5;    
                if(!visit[next.k1][next.k2])
                {
                    copi++;
                    next.cop = copi;
                    copy1[copi] = next;
                    map.push(next);
                    visit[next.k1][next.k2] = 1;
                }
            }
        }
    }
    return ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值