poj3414 Pots

倒水游戏,两个水壶互相倒水,直到某个水壶中的水量到达目标值,若不能到达,输出impossible

这个题完全自己做出来还是感觉很开心的,因为以前在一次比赛上做过,但是没做出来,现在做出来说明还是成长了

广搜,以及路径记录,最后递归输出路径。

#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;

#define M 105

struct Path
{
    int c1, c2;
} pre[M][M];
int v[3], tar, ans;
int d[M][M];

queue <int> q1, q2;

void Fill(int i, int j, const int cur[], int t[])
{
    t[i] = v[i];
    t[j] = cur[j];
}

void Drop(int i, int j, const int cur[], int t[])
{
    t[i] = 0;
    t[j] = cur[j];
}

void Pour(int i, int j, const int cur[], int t[])
{
    if (cur[i] > v[j] - cur[j]) {
       t[j] = v[j];
       t[i] = cur[i] - v[j] + cur[j];
    }
    else {
       t[i] = 0;
       t[j] = cur[j] + cur[i];
    }
}

void Do(int cur[], int t[])
{
     if (!d[t[1]][t[2]]) {
        d[t[1]][t[2]] = d[cur[1]][cur[2]] + 1;
        pre[t[1]][t[2]].c1 = cur[1];
        pre[t[1]][t[2]].c2 = cur[2];
        q1.push(t[1]);
        q2.push(t[2]);
     }
}

bool BFS(int &c1, int &c2)
{
    memset (d, 0, sizeof (d));
    q1.push(0);
    q2.push(0);
    while (!q1.empty()) {
        int cur[3];
        cur[1] = q1.front();
        cur[2] = q2.front();
        q1.pop();
        q2.pop();
        //cout << cur[1] << " " << cur[2] << " " << d[cur[1]][cur[2]] << endl;
        if (cur[1] == tar || cur[2] == tar) {
            c1 = cur[1]; c2 = cur[2];
            ans = d[cur[1]][cur[2]];
            return true;
        }
        int t[3];
        Fill(1, 2, cur, t);
        Do(cur, t);
        Fill(2, 1, cur, t);
        Do(cur, t);
        if (cur[1] == 0 && cur[2] == 0) continue;
        Drop(1, 2, cur, t);
        Do(cur, t);
        Drop(2, 1, cur, t);
        Do(cur, t);
        Pour(1, 2, cur, t);
        Do(cur, t);
        Pour(2, 1, cur, t);
        Do(cur, t);
    }
    return false;
}

void output(int c1, int c2)
{
     if (c1 == 0 && c2 == 0) return;
     int t1 = pre[c1][c2].c1;
     int t2 = pre[c1][c2].c2;
     output(t1, t2);
     if (c1 == v[1] && c2 == t2)
        printf ("FILL(1)\n");
     else if (c2 == v[2] && c1 == t1)
        printf ("FILL(2)\n");
     else if (c1 == 0 && c2 == t2)
        printf ("DROP(1)\n");
     else if (c2 == 0 && c1 == t1)
        printf ("DROP(2)\n");
     else if (t1 > c1 && t2 < c2)
        printf ("POUR(1,2)\n");
     else printf ("POUR(2,1)\n");
}

int main()
{
    scanf ("%d%d%d", &v[1], &v[2], &tar);
    int c1, c2;
    if (BFS(c1, c2)) {
       printf ("%d\n", ans);
       output(c1, c2);
    }
    else printf ("impossible\n");
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值