带方向状态的搜索

来源:互联网 发布:天音淘宝复制大师3.03 编辑:程序博客网 时间:2024/04/29 18:54

zoj 3890 Wumpus

题意:

 一个人掉在一个n*n的洞中,开始位置是(0,0),方向朝右,在这个洞里面有三种东西(1 for Wumpus, 2 for pit and 3 for gold.)这个人每走一步,每转一个方向,爬出坑,捡金子分别都要花掉 ¥10。 求这个人拿到金子和从开始的位置出去的剩钱最多。 

分析:

  因为涉及到方向和捡金子的状态,需要用四维数组标记,另外,三种转换方向的形式(0左转,1右转,2直行),只有在方向与朝向一直才能向前走。

代码:

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<string>#include<map>#include<set>#include<cmath>#include<queue>#include<vector>#include<stack>#include<cstdlib>//#define LL __int64#define LL long long#define pi acos(-1.0)#define PB push_back()#define MP make_pair()#define BG begin()#define ED end()#define clr(a,b)  memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define Mod  1e9+7using namespace std;const int maxn=25;int mp[maxn][maxn];int vis[maxn][maxn][5][2];int n;struct node{    int x,y;    int dir;    int G;    int Mon;    bool operator <(const node& h)const{        return Mon<h.Mon;    }};int dx[4]={-1,1,0,0};              int dy[4]={0,0,-1,1};bool in(int x,int y){    return x>=0&&x<n&&y>=0&&y<n;       //1 for Wumpus, 2 for pit and 3 for gold.}int Change(int dir,int ch){    if(dir==0 && ch==0) return 2;    if(dir==0 && ch==1) return 3;    if(dir==1 && ch==0) return 3;    if(dir==1 && ch==1) return 2;    if(dir==2 && ch==0) return 1;    if(dir==2 && ch==1) return 0;    if(dir==3 && ch==0) return 0;    if(dir==3 && ch==1) return 1;}int bfs(int xx,int yy){    if(mp[xx][yy]==2)  return -1;    clr(vis,0);    node st,ed;    priority_queue<node> PQ;    st.x=xx;    st.y=yy;    st.dir=1;    st.G=0;    st.Mon=0;    vis[st.x][st.y][st.dir][st.G]=1;    PQ.push(st);    while(!PQ.empty())    {        st=PQ.top();        PQ.pop();        if(st.x==0&&st.y==0&&st.G==1)            return st.Mon-10;        for(int i=0;i<3;i++){            if(i!=2){                ed=st;                ed.dir=Change(st.dir,i);                ed.Mon=st.Mon-10;                if(vis[st.x][st.y][ed.dir][ed.G]==0){                    vis[st.x][st.y][ed.dir][ed.G]=1;                    PQ.push(ed);                }                continue;            }            int zx=st.x+dx[st.dir];            int zy=st.y+dy[st.dir];            if(in(zx,zy)&&vis[zx][zy][st.dir][st.G]==0&&mp[zx][zy]!=1&&mp[zx][zy]!=2){                vis[zx][zy][st.dir][st.G]=1;                ed.x=zx;                ed.y=zy;                ed.Mon=st.Mon-10;                ed.dir=st.dir;                ed.G=st.G;                if(mp[zx][zy]==3)  { ed.Mon+=990; ed.G=1;}                PQ.push(ed);            }        }    }    return -1;}int main(){     #ifndef ONLINE_JUDGE      freopen("in.cpp","r",stdin);     #endif // ONLINE_JUDGE      int T;      cin>>T;      while(T--){        scanf("%d",&n);        int s,xx,yy;        clr(mp,0);        while(~scanf("%d%d%d",&s,&xx,&yy)){            if(s==-1&&xx==-1&&yy==-1)  break;            mp[xx][yy]=s;        }        int cnt=0;        cnt=bfs(0,0);        cout<<cnt<<endl;      }    return 0;}
0 0
原创粉丝点击