题意:
一个人掉在一个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+7
using 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
}
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
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
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
}