Pots (广搜+回溯)

题目来源https://vjudge.net/contest/159739#problem/H
【题意】
两只水杯,给出各自的容量,初始都没有存水,接着给出六种操作,问经过多次操作后,判断能不能到达一种给出的状态。
【思路】
利用结构体里定义二维字符串,每经过依次操作,都要把它上一步含有的所有操作全都复制下来,那么到最后找到的时候,里面存的就是正确的操作了。
【代码】

#include<stack>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<map>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
int vis[110][110];
int A,B,C;
struct djh
{
    int v1,v2,t;
    string str[120];
} q1,q2;
void bfs()
{
    queue<djh> q;
    q1.v1=0;
    q1.v2=0;
    q1.t=0;
    q.push(q1);
    vis[q1.v1][q1.v2]=1;
    while(!q.empty())
    {
        q1=q.front();
        q.pop();
        if(q1.v1==C||q1.v2==C)
        {
            printf("%d\n",q1.t);
            for(int i=1; i<=q1.t; i++)
                cout<<q1.str[i]<<endl;
            return;
        }
        if(q1.v1!=A)
        {

            q2=q1;
            q2.v1=A;
            q2.str[++q2.t]="FILL(1)";

            if(!vis[q2.v1][q2.v2])
            {
                vis[q2.v1][q2.v2]=1;
                q.push(q2);
            }
        }
        if(q1.v2!=B)
        {
            q2=q1;
            q2.v2=B;
            q2.str[++q2.t]="FILL(2)";

            if(!vis[q2.v1][q2.v2])
            {
                vis[q2.v1][q2.v2]=1;
                q.push(q2);
            }
        }
        if(q1.v1!=0)
        {
            q2=q1;
            q2.v1=0;
            q2.str[++q2.t]="DROP(1)";

            if(!vis[q2.v1][q2.v2])
            {
                vis[q2.v1][q2.v2]=1;
                q.push(q2);
            }
        }
        if(q1.v2!=0)
        {
            q2=q1;
            q2.v2=0;
            q2.str[++q2.t]="DROP(2)";

            if(!vis[q2.v1][q2.v2])
            {
                vis[q2.v1][q2.v2]=1;
                q.push(q2);
            }
        }
        if(q1.v1!=0&&q1.v2!=B)
        {
            q2=q1;
            int r=q2.v1+q2.v2;
            q2.v1=r>B?r-B:0;
            q2.v2=r>B?B:r;
            q2.str[++q2.t]="POUR(1,2)";

            if(!vis[q2.v1][q2.v2])
            {
                vis[q2.v1][q2.v2]=1;
                q.push(q2);
            }
        }
        if(q1.v1!=A&&q1.v2!=0)
        {
            q2=q1;
            int r=q2.v1+q2.v2;
            q2.v2=r>A?r-A:0;
            q2.v1=r>A?A:r;
            q2.str[++q2.t]="POUR(2,1)";
            if(!vis[q2.v1][q2.v2])
            {
                vis[q2.v1][q2.v2]=1;
                q.push(q2);
            }
        }
    }
    printf("impossible\n");
    return ;
}
int main()
{
    scanf("%d%d%d",&A,&B,&C);
    bfs();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值