码迷,mamicode.com
首页 > 其他好文 > 详细

POJ3414 Pots

时间:2016-08-15 10:25:58      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:

问题链接POJ3414 Pots

题意简述给出两个壶的容量A和B, 一个目标水量C,对A、B可以有3种操作,求最少经过几步操作能够在某个壶中得到目标水量C。输入A、B和C,输入最少操作数和操作过程。

  1. FILL(i)     fill the pot i (1 ≤ i ≤ 2) from the tap;
  2. DROP(i)     empty the pot i to the drain;
  3. POUR(i,j)    pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).

问题分析:把A和B壶中水量作为状态,初始状态为<0,0>,每个操作都是状态变化的过程。因为有2个壶,所以总共有6种操作。使用BFS搜索来找到最少的操作步数。同时需要考虑操作的条件,以减少操作来加快程序运行速度。

程序说明:搜索过的状态就不需要再搜索了,用数组notvist[][]来标记搜索过的状态。操作的前提条件已经写在程序中。

AC的C++语言程序如下:

/* POJ3414 Pots */

#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

const int MAXN = 100;

int a, b, c;
bool notvist[MAXN+1][MAXN+1];

struct node {
    int a, b, level;
    char path[MAXN+1];
    int plen;
};

string path[] = {
     "FILL(1)"
    ,"FILL(2)"
    ,"DROP(1)"
    ,"DROP(2)"
    ,"POUR(1,2)"
    ,"POUR(2,1)"
};

void output_result(int lvl, char p[], int n)
{
    cout << lvl << endl;
    for(int i=0; i<n; i++)
        cout << path[(int)p[i]] << endl;
}

void bfs()
{
    queue<node> q;

    memset(notvist, true, sizeof(notvist));

    node f;
    f.a = 0;
    f.b = 0;
    f.level = 0;
    memset(f.path, 0, sizeof(f.path));
    f.plen = 0;
    q.push(f);

    notvist[f.a][f.b] = false;

    while(!q.empty()) {
        f = q.front();
        q.pop();

        if(f.a == c || f.b == c) {
            output_result(f.level, f.path, f.plen);
            return;
        }

        node v;

        v = f;
        v.level++;
        v.plen++;
        // FILL(a)
        if(a - f.a > 0) {
            v.a = a;
            v.b = f.b;
            if(notvist[v.a][v.b]) {
                v.path[f.plen] = 0;
                q.push(v);
                notvist[v.a][v.b] = false;
            }
        }
        // FILL(b)
        if(b - f.b > 0) {
            v.a = f.a;
            v.b = b;
            if(notvist[v.a][v.b]) {
                v.path[f.plen] = 1;
                q.push(v);
                notvist[v.a][v.b] = false;
            }
        }
        // DROP(a)
        if(f.a) {
            v.a = 0;
            v.b = f.b;
            if(notvist[v.a][v.b]) {
                v.path[f.plen] = 2;
                q.push(v);
                notvist[v.a][v.b] = false;
            }
        }
        // DROP(b)
        if(f.b) {
            v.a = f.a;
            v.b = 0;
            if(notvist[v.a][v.b]) {
                v.path[f.plen] = 3;
                q.push(v);
                notvist[v.a][v.b] = false;
            }
        }
        // POUR(a,b)
        if(f.a && (f.b < b)) {
            if(f.a > (b - f.b)) {
                v.a = f.a -(b - f.b);
                v.b = b;
            } else {
                v.a = 0;
                v.b = f.b + f.a;
            }
            if(notvist[v.a][v.b]) {
                v.path[f.plen] = 4;
                q.push(v);
                notvist[v.a][v.b] = false;
            }
        }
        // POUR(b,a)
        if(f.b && (f.a < a)) {
            if(f.b > (a - f.a)) {
                v.a = a;
                v.b = f.b -(a - f.a);
            } else {
                v.a = f.a + f.b;
                v.b = 0;
            }
            if(notvist[v.a][v.b]) {
                v.path[f.plen] = 5;
                q.push(v);
                notvist[v.a][v.b] = false;
            }
        }
    }

    cout << "impossible" << endl;
}

int main()
{
    cin >> a >> b >> c;

    bfs();

    return 0;
}


POJ3414 Pots

标签:

原文地址:http://blog.csdn.net/tigerisland45/article/details/52208174

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!