1. 程式人生 > >搜尋初探 Pots POJ

搜尋初探 Pots POJ

做這題的時候,沒有思路,覺得暴力的話,狀態可能會爆炸。 但是每一個狀態,最多隻有六個後繼狀態,並且資料量很小,可以使用bfs列舉得出最短路

搜尋的時候,怎麼判斷該狀態是否已經經過了呢,可以使用 visit陣列。

所以這題最重要的就是關注到狀態轉移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;
}