搜索初探 Pots POJ - 3414

做这题的时候,没有思路,觉得暴力的话,状态可能会爆炸。
但是每一个状态,最多只有六个后继状态,并且数据量很小,可以使用bfs枚举得出最短路

搜索的时候,怎么判断该状态是否已经经过了呢,可以使用 visit数组。因为每个瓶子最大容量是 30 两个瓶子的组合才 900 ,容量空间非常小。

所以这题最重要的就是关注到状态转移visit 数组


另外还有一点就是学习了如何打印 bfs路径
可以使用一维数组存储所有的枚举过的状态,然后使用链式前向星的思想,记录每一个节点的前驱结点。
关键点在于每一个 节点的父亲节点是唯一的,每一个节点的孩子节点却有多个。
这是一个多叉图,而不是网状图。

#include<iostream>
#include<vector>
#include<queue>
#include<string>
#include<cstring>

using namespace std;

int  va,vb,vc;
struct node
{
    int father;
    int a;
    int b;

    int x;  //操作几
    int y;  //对谁操作

}num[10005];


vector<int> path;
queue<int> qu;

int vis[105][105];


int counts;
int flag;
void bfs()
{
    counts=0;
    num[counts].a = 0;
    num[counts].b = 0;
    num[counts].father = -1;
    qu.push(counts);
    vis[num[counts].a][num[counts].b] = 1;   //如果这个点已经进入队列就不用再进队了  因为在此之前  一定步数更少
    counts++;

    while(!qu.empty())
    {
        int p = qu.front();
        node f = num[p];

        qu.pop();

        if(f.a==vc||f.b==vc)
        {
            flag =p;
            break;
        }
        //操作 a
        //填满
        if(f.a< va&&vis[va][f.b]!=1)
        {

            num[counts].a = va;
            num[counts].b = f.b;
            num[counts].father =p ;
            num[counts].x = 1;
            num[counts].y = 0;

            qu.push(counts);
            vis[num[counts].a][num[counts].b]=1;
            counts++;
        }

        //清空
        if(f.a >0 &&vis[0][f.b]!=1)
        {
            num[counts].a = 0;
            num[counts].b = f.b;
            num[counts].father = p;
            num[counts].x = 2;
            num[counts].y = 0;

            qu.push(counts);
            vis[num[counts].a][num[counts].b]=1;
            counts++;

        }

        // a -> b
        if(f.a >0 &&f.b<vb)
        {
            int aa;
            int bb;
            if(f.a > vb-f.b)
            {
                aa = f.a -vb+f.b;
                bb = vb;
            }
            else
            {
                aa = 0;
                bb = f.a+f.b;
            }
            if(vis[aa][bb]!=1)
            {
                num[counts].a = aa;
                num[counts].b = bb;
                num[counts].father = p;
                num[counts].x = 3;
                num[counts].y = 0;

                qu.push(counts);
                vis[num[counts].a][num[counts].b]=1;
                counts++;
            }

        }

        //操作 b
        //填满
        if(f.b<vb &&vis[f.a][vb]!=1)
        {
            num[counts].a = f.a;
            num[counts].b = vb;
            num[counts].father = p;
            num[counts].x = 1;
            num[counts].y = 1;

            qu.push(counts);
            vis[num[counts].a][num[counts].b]=1;
            counts++;

        }

        //清空
        if(f.b >0 &&vis[f.a][0]!=1)
        {
            num[counts].a = f.a;
            num[counts].b = 0;
            num[counts].father = p;
            num[counts].x = 2;
            num[counts].y = 1;

            qu.push(counts);
            vis[num[counts].a][num[counts].b]=1;
            counts++;

        }
        // b -> a
        if(f.b >0 &&f.a<va)
        {
            int aa;
            int bb;
            if(f.b > va-f.a)
            {
                aa = va;
                bb = f.b - va+f.a;
            }
            else
            {
                aa = f.a+f.b;
                bb = 0;
            }
            if(vis[aa][bb]!=1)
            {
                num[counts].a = aa;
                num[counts].b = bb;
                num[counts].father = p;
                num[counts].x = 3;
                num[counts].y = 1;

                qu.push(counts);
                vis[num[counts].a][num[counts].b]=1;
                counts++;
            }
        }

    }
    while(!qu.empty())qu.pop();
}
string op[3] = {"FILL","DROP","POUR"};

void shows(int i)
{
    int x = num[i].x;
    int y = num[i].y;
    if(x==1)
    {
        if(y==0)cout<<"FILL(1)"<<endl;
        else  cout<<"FILL(2)"<<endl;
    }else if(x==2){
        if(y==0) cout<<"DROP(1)"<<endl;
        else    cout<<"DROP(2)"<<endl;

    }else if(x==3){
        if(y==0) cout<<"POUR(1,2)"<<endl;
        else     cout<<"POUR(2,1)"<<endl;
    }

}
int main()
{
    ios::sync_with_stdio(false);
    while(cin>>va>>vb>>vc)
    {

        flag =-1;
        memset(vis,0,sizeof(vis));
        bfs();
        if(flag == -1)
        {
            cout<<"impossible"<<endl;
        }else{
              path.clear();

              while(flag!=-1)
              {
                   path.push_back(flag);
                   flag = num[flag].father;
              }
              cout<<path.size()-1<<endl;
              for(int i = path.size()-1;i>=0;i--)
              {
                  shows(path[i]);
              }

        }

    }

        return 0;
}

猜你喜欢

转载自blog.csdn.net/jackcily/article/details/82999007