zoukankan      html  css  js  c++  java
  • 游戏机器人

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

    游戏机器人

    时间限制: 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
    ",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 }
  • 相关阅读:
    mariadb
    Linux下安装配置virtualenv与virtualenvwrapper
    配置安装源
    Redis哨兵
    Android 常用工具类之DeviceInfoUtil
    Android 常用工具类之RuntimeUtil
    android 中的几种目录
    listview 滑动以后设置最上面一行为整行展示
    Android 常用工具类之SPUtil,可以修改默认sp文件的路径
    android 在应用中切换语言
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7210405.html
Copyright © 2011-2022 走看看