POJ - 3414(BFS,标记路径)

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

Description

You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

  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).

Write a program to find the shortest possible sequence of these operations that will yield exactly C liters of water in one of the pots.

Input

On the first and only line are the numbers A, B, and C. These are all integers in the range from 1 to 100 and C≤max(A,B).

Output

The first line of the output must contain the length of the sequence of operations K. The following K lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.

Sample Input

3 5 4

Sample Output

 
 

6  FILL(2)  POUR(2,1)  DROP(1)  POUR(2,1)  FILL(2)  POUR(2,1)

题意:       给你两个水壶,容量分别是A,B。问你最少进行几步操作可以得到一个装有C体积的水壶,并写出操作步骤,若不可能输出"impossibe"。

思路:

  1. 对于每个水壶都有3种操作,倒空、倒满、倒入另一个,所以一共有6种操作,倒入另一个时要分两种情况讨论。6种不同操作可以用for配合switch。
  2. 路径的记录:后一点记录(“连接”)前一点,输出时采用递归形式。
  3. 因为是搜索,所以标记很重要,把已经查找过得点标记,防止重复查找,可采用二维数组。
  4. 点(node)是每个操作的抽象,内部应有数据:a(A容器内水体积),b(B容器内水体积),s(进行到此状态的耗费的(最少)步骤),flag(进行了什么操作),node* pre(连接前一点,形成“轨迹”)。

AC代码:

#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
struct Node
{
    int a,b,s,flag;
    Node* pre;
    Node(){};
    Node( int a1,int b1,int s1,int f,Node* p )
    {
        a=a1,b=b1,s=s1,flag=f,pre=p;
    }
}ne[777];
queue<Node> iq;
int a,b,c,cnt;  //cnt记录节点总数,得用数组ne,否则节点会消失
int vir[108][108]={0};

void ShowRoad( Node x )  //递归输出
{
    if( x.s != 0 )
    ShowRoad( *x.pre );

    switch( x.flag )
    {
        case 1:printf("DROP(1)\n"); break;
        case 2:printf("DROP(2)\n"); break;
        case 3:printf("FILL(1)\n"); break;
        case 4:printf("FILL(2)\n"); break;
        case 5:printf("POUR(1,2)\n");break;
        case 6:printf("POUR(2,1)\n");break;
    }
}

void bfs()
{
    cnt = 0 ;
    iq.push(Node(0,0,0,0,NULL));
    while( !iq.empty() )
    {
        ne[++cnt]=iq.front();
        vir[ne[cnt].a][ne[cnt].b]=1;
        iq.pop();

        if( ne[cnt].a==c || ne[cnt].b==c )
        {
            printf("%d\n",ne[cnt].s);
            ShowRoad(ne[cnt]);
            return ;
        }

        for( int i=1; i<=6; i++ )       //六种操作
        {
            switch( i )
            {
                case 1:
                    if( !vir[0][ne[cnt].b] )
                    iq.push(Node(0,ne[cnt].b,ne[cnt].s+1,1,&ne[cnt])); break;
                case 2:
                    if( !vir[ne[cnt].a][0] )
                    iq.push(Node(ne[cnt].a,0,ne[cnt].s+1,2,&ne[cnt])); break;
                case 3:
                    if( !vir[a][ne[cnt].b] )
                    iq.push(Node(a,ne[cnt].b,ne[cnt].s+1,3,&ne[cnt])); break;
                case 4:
                    if( !vir[ne[cnt].a][b] )
                    iq.push(Node(ne[cnt].a,b,ne[cnt].s+1,4,&ne[cnt])); break;
                case 5:
                    {
                        if( ne[cnt].a + ne[cnt].b > b && !vir[ne[cnt].a+ne[cnt].b-b][b] )
                        iq.push(Node(ne[cnt].a+ne[cnt].b-b,b,ne[cnt].s+1,5,&ne[cnt]));
                        else if( ne[cnt].a + ne[cnt].b < b && !vir[0][ne[cnt].a+ne[cnt].b] )
                        iq.push(Node(0,ne[cnt].a+ne[cnt].b,ne[cnt].s+1,5,&ne[cnt]));
                        break;
                    }
                case 6:
                    {
                        if( ne[cnt].a + ne[cnt].b > a && !vir[a][ne[cnt].a+ne[cnt].b-a] )
                        iq.push(Node(a,ne[cnt].a+ne[cnt].b-a,ne[cnt].s+1,6,&ne[cnt]));
                        else if( ne[cnt].a + ne[cnt].b < a &&!vir[ne[cnt].a+ne[cnt].b][0] )
                        iq.push(Node(ne[cnt].a+ne[cnt].b,0,ne[cnt].s+1,6,&ne[cnt]));
                        break;
                    }
            }
        }
    }
    printf("impossible\n");
}

int main()
{
    scanf("%d%d%d",&a,&b,&c); //只输入一次
    bfs();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40764917/article/details/80919172