游戏机器人
来源:互联网 发布:被一个人爱的感觉知乎 编辑:程序博客网 时间:2024/05/16 10:28
题目描述
让我们来玩一个机器人游戏,游戏在一个长方形网格上进行,机器人最初被安放在长方形网格的左上角且面朝东,而游戏的目标就是使到达右下网格。
机器人可以执行以下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
最短路+裂点,其实就是对每个点分裂成不同方向的四个点。
然后进行添边的分类大讨论,这部分代码重载率很高,可以用循环和子程序尽量缩短代码。
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#define ll long longusing namespace std;int n,m,x,y,t,w,id,tot,all,ans,d1,d2,d3,d4,c1,c2,c3,c4;int head[4005],Next[80005],to[80005],len[80005];int f[4005],p[4005],g[100005];int a[35][35],dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};int work(int x,int y,int z){ return ((x-1)*m+y-1)*4+z;}void add(int x,int y,int ok,int z){ tot++; Next[tot]=head[x]; to[tot]=y; if(ok==1) len[tot]=0;else len[tot]=z; head[x]=tot;}void spfa(){ for(int i=2;i<=all;i++) f[i]=1e9; t=0;w=1; g[1]=1; f[1]=0; while(t<w) { t++; x=g[t]; p[x]=0; for(int i=head[x];i!=-1;i=Next[i]) if(f[x]+len[i]<f[to[i]]) { f[to[i]]=f[x]+len[i]; if(p[to[i]]==0) { w++; g[w]=to[i]; p[to[i]]=1; } } }}int main(){ cin>>m>>n; all=n*m*4; for(int i=1;i<=all;i++) head[i]=-1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&a[i][j]); a[i][j]++; } cin>>c1>>c2>>c3>>c4; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { d1=work(i,j,1); //east d2=work(i,j,2); //south d3=work(i,j,3); //west d4=work(i,j,4); //north if(j+1<=m) add(d1,work(i,j+1,1),a[i][j]==1,c1); //Straight if(i+1<=n) add(d2,work(i+1,j,2),a[i][j]==1,c1); if(j-1>=1) add(d3,work(i,j-1,3),a[i][j]==1,c1); if(i-1>=1) add(d4,work(i-1,j,4),a[i][j]==1,c1); if(i+1<=n) add(d1,work(i+1,j,2),a[i][j]==2,c2); //Right if(j-1>=1) add(d2,work(i,j-1,3),a[i][j]==2,c2); if(i-1>=1) add(d3,work(i-1,j,4),a[i][j]==2,c2); if(j+1<=m) add(d4,work(i,j+1,1),a[i][j]==2,c2); if(j-1>=1) add(d1,work(i,j-1,3),a[i][j]==3,c3); //Back if(i-1>=1) add(d2,work(i-1,j,4),a[i][j]==3,c3); if(j+1<=m) add(d3,work(i,j+1,1),a[i][j]==3,c3); if(i+1<=n) add(d4,work(i+1,j,2),a[i][j]==3,c3); if(i-1>=1) add(d1,work(i-1,j,4),a[i][j]==4,c4); //Left if(j+1<=m) add(d2,work(i,j+1,1),a[i][j]==4,c4); if(i+1<=n) add(d3,work(i+1,j,2),a[i][j]==4,c4); if(j-1>=1) add(d4,work(i,j-1,3),a[i][j]==4,c4); } spfa(); ans=f[work(n,m,1)]; ans=min(ans,f[work(n,m,2)]); ans=min(ans,f[work(n,m,3)]); ans=min(ans,f[work(n,m,4)]); cout<<ans; return 0;}
- 游戏机器人
- 机器人游戏
- 游戏机器人
- 游戏机器人(1)
- 游戏机器人(2)
- 游戏机器人(3)
- 游戏挂机机器人框架
- [JZOJ5046]机器人游戏
- 【NOI2017】机器人游戏
- 【编程游戏】划拳机器人比赛
- android数独游戏机器人
- 【NOI2017模拟4.5】机器人游戏
- 网络机器人(2)----开发游戏机器人所需要的基本功
- 网络机器人----开发游戏机器人所需要的基本功 zz
- 网络机器人(2)----开发游戏机器人所需要的基本功
- 网络机器人(2)----开发游戏机器人所需要的基本功
- 网络机器人(2)----开发游戏机器人所需要的基本功
- 网络机器人(2)----开发游戏机器人所需要的基本功
- sqoop-1.99.3安装
- 最小割Stoer-Wagner算法模板hdu3691
- hdu 1043 eight (搜索 + 康托展开)
- hdu2612 Find a way--BFS & 打表
- 2015 Multi-University Training Contest 3
- 游戏机器人
- android搭建开发环境
- 关于Linux 下的错误路由产生火星包的问题
- 格式化时间
- C#的第7节课
- Python新手学习基础之运算符——赋值与逻辑运算
- ubuntu使用技巧
- hdu 1885 key task (搜索)
- 8.竞态条件和临界段