游戏机器人

现在主要讲讲建边的问题,许多图难就难在建边上,建完边后就是简单的裸题什么之类的,游戏机器人就是这样一道题。

游戏机器人

时间限制: 1 Sec  内存限制: 128 MB
提交: 77  解决: 43
[提交][状态][讨论版]

题目描述

让我们来玩一个机器人游戏,游戏在一个长方形网格上进行,机器人最初被安放在长方形网格的左上角且面朝东,而游戏的目标就是使到达右下网格。 

机器人可以执行以下5种操作: 

"Straight": 保持机器人当前的方向,并前进一格。 
"Right": 右转90度,并前进一格 
"Back": 转180度,并前进一格 
"Left": 左转90度,并前进一格 
"Halt": 停在原地,并结束游戏。 

机器人可以经过同一个方块多次。如果你在游戏过程中,让机器人走出边界或者在到达目标之前执行了“Halt”指令,你都将失败。 

现在你的任务是计算最小的代价,使机器人从起点到达终点。 

 

 

输入

文件开始两个整数w,h,表示列和行数(2 ≤ h ≤ 30 ,2 ≤ w ≤ 30) 
接下来共h行w列整数 
最后4个整数c0 c1 c2 c3。 
格式如下: 
w h 
s(1,1) ... s(1,w) 
s(2,1) ... s(2,w) 
... 
s(h,1) ... s(h,w) 
c0 c1 c2 c3 
矩阵中数字代表的含义如下: 
0: "Straight" 
1: "Right" 
2: "Back" 
3: "Left" 
4: "Halt" 
保证“Halt”命令将出现在目标位置,但也可能出现在矩阵中某个方格中。 
最后4个数字c0, c1, c2, 和c3, 分别表示你使用"Straight", "Right", "Back", and "Left" 命令的代价,其值在1~9之间。 

输出

输出机器人从起点到终点的最小代价。

样例输入

8 3
0 0 0 0 0 0 0 1
2 3 0 1 4 0 0 1
3 3 0 0 0 0 0 4
9 9 1 9

样例输出

1

提示

30%数据w,h<10 
100%数据w,h<=30 

裂点+Dijkstra ,建图其实一般人都看的出来,但是想着想着就是十分困难的,然后就Give up!了,像这种网格图,Spfa貌似没什么优势,但是点又比较多,一格裂成4个点,但是数据范围比较小,时间复杂度还是可以的。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstring>
  6 #include<queue>
  7 using namespace std;
  8  
  9 const int WW=37,HH=37;
 10 typedef pair<int,int> fzy;
 11  
 12 int n,m,S,T;
 13 int a[WW][HH],b[5];
 14 int dis[WW*HH*5],cnt,head[WW*HH*5],next[WW*HH*HH],val[WW*HH*HH],rea[WW*HH*HH];
 15 struct cmp
 16 {
 17     bool operator()(fzy a,fzy b)
 18     {return a.first>b.first;}
 19 };
 20 priority_queue<fzy,vector<fzy>,cmp>q;
 21  
 22 void add(int u,int v,int fee)
 23 {
 24     cnt++;
 25     next[cnt]=head[u];
 26     head[u]=cnt;
 27     rea[cnt]=v;
 28     val[cnt]=fee;
 29 }
 30 int edg(int x,int y)
 31 {
 32     if (x==y) return 0;
 33     return b[y];
 34 }
 35 void make(int i,int j)
 36 {
 37     int u=((i-1)*m+j-1)*4+1;
 38     if (j+1<=m) add(u,((i-1)*m+j)*4+1,edg(a[i][j],0));
 39     if (i+1<=n) add(u,(i*m+j-1)*4+2,edg(a[i][j],1));
 40     if (j-1>=1) add(u,((i-1)*m+j-2)*4+3,edg(a[i][j],2));
 41     if (i-1>=1) add(u,((i-2)*m+j-1)*4+4,edg(a[i][j],3));
 42      
 43     u=((i-1)*m+j-1)*4+2;
 44     if (i+1<=n) add(u,(i*m+j-1)*4+2,edg(a[i][j],0));
 45     if (j-1>=1) add(u,((i-1)*m+j-2)*4+3,edg(a[i][j],1));
 46     if (i-1>=1) add(u,((i-2)*m+j-1)*4+4,edg(a[i][j],2));
 47     if (j+1<=m) add(u,((i-1)*m+j)*4+1,edg(a[i][j],3));
 48      
 49     u=((i-1)*m+j-1)*4+3;
 50     if (j-1>=1) add(u,((i-1)*m+j-2)*4+3,edg(a[i][j],0));
 51     if (i-1>=1) add(u,((i-2)*m+j-1)*4+4,edg(a[i][j],1));
 52     if (j+1<=m) add(u,((i-1)*m+j)*4+1,edg(a[i][j],2));
 53     if (i+1<=n) add(u,(i*m+j-1)*4+2,edg(a[i][j],3));
 54      
 55     u=((i-1)*m+j-1)*4+4;
 56     if (i-1>=1) add(u,((i-2)*m+j-1)*4+4,edg(a[i][j],0));
 57     if (j+1<=m) add(u,((i-1)*m+j)*4+1,edg(a[i][j],1));
 58     if (i+1<=n) add(u,(i*m+j-1)*4+2,edg(a[i][j],2));
 59     if (j-1>=1) add(u,((i-1)*m+j-2)*4+3,edg(a[i][j],3));
 60 }
 61 void Dijkstra()
 62 {
 63     bool boo[4007];
 64     memset(boo,0,sizeof(boo));
 65     memset(dis,100,sizeof(dis));
 66     dis[S]=0;
 67     q.push(make_pair(0,S));
 68     while (!q.empty())
 69     {
 70         fzy now=q.top();
 71         q.pop();
 72         if (boo[now.second]) continue;
 73         boo[now.second]=1;
 74         int u=now.second;
 75         for (int i=head[u];i!=-1;i=next[i])
 76         {
 77             int v=rea[i],fee=val[i];
 78             if (dis[u]+fee<dis[v]&&!boo[v])
 79             {
 80                 dis[v]=dis[u]+fee;
 81                 q.push(make_pair(dis[v],v));
 82             }
 83         }
 84     }
 85     printf("%d\n",dis[T]);
 86 }
 87 int main()
 88 {
 89     cnt=0;
 90     memset(head,-1,sizeof(head));
 91     scanf("%d%d",&m,&n);
 92     for (int i=1;i<=n;i++)
 93         for (int j=1;j<=m;j++)
 94              scanf("%d",&a[i][j]);
 95     a[n][m]=-1;
 96     for (int i=0;i<=3;i++)
 97         scanf("%d",&b[i]);      
 98     for (int i=1;i<=n;i++)
 99         for (int j=1;j<=m;j++)
100             make(i,j);
101              
102     S=n*m*4+1,T=n*m*4+2;
103     add(S,1,0);
104     add((n*m-1)*4+1,T,0),add((n*m-1)*4+2,T,0),add((n*m-1)*4+3,T,0),add((n*m-1)*4+4,T,0);
105     Dijkstra();     
106 }

 

posted @ 2017-07-20 11:47  Kaiser-  阅读(240)  评论(0编辑  收藏  举报