POJ 3414 Pots (BFS搜索题)

/**
 *  搜索题 BFS:
 *  关键就是 状态转移,和判重。
 *  这里用isVis[i][j]表示之前搜索的时候是否访问过a桶和b桶存有i j升水
 *  如果访问过则不再加入队列。  因为题目要求的是最短路径,如果再次访问,
 *  所需操作次数必然更大,所以当第一次访问的时候就要设vis的值为1表示已访问。
 *  答案输出我用的是stack栈去存储。 因为之前在每次放入队列的时候都记录了前一个状态。
 *  Node结构体的设计: a, b 分别表示两桶存的水量
 *                     prePos 之前一个状态的下标
 *                     type 是之前一个状态到当前状态所采取的的操作类型
 *                     12表示 POUR(1,2)       21 反之
 *                     1 表示 FILL a          2  亦同
 *                     10表示 DROP a          20 亦同     ———— 1A
 */ 

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#define INF 0x7fffffff
#define MAXS 10010
#define LL long long
using namespace std;
struct Node {
    int a, b;
    int prePos, type;  // 12 21 1 2 10 20
} nodes[MAXS];
int oriA, oriB, des;
int ansStack[101], top, rear, front;
int isVis[101][101];

void print() {
    printf("%d\n", top);
    top --;
    while(top != -1) {
        if(ansStack[top] == 1)
            printf("FILL(1)\n");
        else if(ansStack[top] == 2)
            printf("FILL(2)\n");
        else if(ansStack[top] == 12)
            printf("POUR(1,2)\n");
        else if(ansStack[top] == 21)
            printf("POUR(2,1)\n");
        else if(ansStack[top] == 10)
            printf("DROP(1)\n");
        else if(ansStack[top] == 20)
            printf("DROP(2)\n");
        top --;
    }
}

int main()
{
    while(scanf("%d%d%d", &oriA, &oriB, &des) != EOF) {
        int a, b, ans, found;
        a = b = rear = found = top = 0;
        front = 0;
        memset(isVis, 0, sizeof(isVis));
        isVis[0][0] = 1;

        Node newNode;
        newNode.a = newNode.b = 0;
        newNode.prePos = ans = -1;
        nodes[rear++] = newNode;

        while(front < rear && !found) {
            //int curPre = front;
            newNode = nodes[front];
            newNode.prePos = front;
            if(newNode.a == des || newNode.b == des) {
                found = 1;
                ans = front;
                break;
            }

            // drop a
            if(newNode.a && !isVis[0][newNode.b]) {
                newNode.a = 0;
                newNode.type = 10;
                nodes[rear++] = newNode;
                isVis[0][newNode.b] = 1;
                newNode.a = nodes[front].a;
            }
            // drop b
            if(newNode.b && !isVis[newNode.a][0]) {
                newNode.b = 0;
                newNode.type = 20;
                nodes[rear++] = newNode;
                isVis[newNode.a][0] = 1;
                newNode.b = nodes[front].b;
            }
            // fill a
            if(newNode.a != oriA && !isVis[oriA][newNode.b]) {
                newNode.a = oriA;
                newNode.type = 1;
                nodes[rear++] = newNode;
                isVis[oriA][newNode.b] = 1;
                newNode.a = nodes[front].a;
            }
            // fill b
            if(newNode.b != oriB && !isVis[newNode.a][oriB]) {
                newNode.b = oriB;
                newNode.type = 2;
                nodes[rear++] = newNode;
                isVis[newNode.a][oriB] = 1;
                newNode.b = nodes[front].b;
            }
            // pour a to b
            if(newNode.a && newNode.b != oriB) {
                newNode.b += newNode.a;
                newNode.a = 0;
                if(newNode.b > oriB) {
                    newNode.a = newNode.b - oriB;
                    newNode.b = oriB;
                }
                if(!isVis[newNode.a][newNode.b]) {
                    newNode.type = 12;
                    nodes[rear++] = newNode;
                    isVis[newNode.a][newNode.b] = 1;
                }
                newNode.a = nodes[front].a;
                newNode.b = nodes[front].b;
            }
            // pour b to a
            if(newNode.b && newNode.a != oriA) {
                newNode.a += newNode.b;
                newNode.b = 0;
                if(newNode.a > oriA) {
                    newNode.b = newNode.a - oriA;
                    newNode.a = oriA;
                }
                if(!isVis[newNode.a][newNode.b]) {
                    newNode.type = 21;
                    nodes[rear++] = newNode;
                    isVis[newNode.a][newNode.b] = 1;
                }
                newNode.a = nodes[front].a;
                newNode.b = nodes[front].b;
            }
            front ++;
        }

        if(ans == -1) {
            printf("impossible\n");
            continue;
        }

        while(nodes[ans].prePos != -1) {
            ansStack[top++] = nodes[ans].type;
            ans = nodes[ans].prePos;
        }

        print();

    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值