专题一搜索 D - 驾驶卡丁车
- 题目
小Q正在设计一款2D卡丁车游戏,你的任务是帮助小Q实现其中的一部分功能。
在这款游戏中,游戏地图是一张 nn 行 mm 列的网格,从上到下依次编号为第 11 行到第 nn 行,从左往右依次编号为第 11 列到第 mm 列,其中第 ii 行第 jj 列的格子的坐标为 (i,j)(i,j),每个格子要么是可以通行的平地,要么是不可通行的障碍。
在地图上的某个平地格子处有一辆由玩家操控的卡丁车。卡丁车的移动速率为 vv,并且一共有8种可能的朝向,分别为:
- "上":前进一步时,将从 (x,y)(x,y) 移动到 (x-1,y)(x−1,y)。
- "下":前进一步时,将从 (x,y)(x,y) 移动到 (x+1,y)(x+1,y)。
- "左":前进一步时,将从 (x,y)(x,y) 移动到 (x,y-1)(x,y−1)。
- "右":前进一步时,将从 (x,y)(x,y) 移动到 (x,y+1)(x,y+1)。
- "左上":前进一步时,将从 (x,y)(x,y) 移动到 (x-1,y-1)(x−1,y−1)。
- "右上":前进一步时,将从 (x,y)(x,y) 移动到 (x-1,y+1)(x−1,y+1)。
- "左下":前进一步时,将从 (x,y)(x,y) 移动到 (x+1,y-1)(x+1,y−1)。
- "右下":前进一步时,将从 (x,y)(x,y) 移动到 (x+1,y+1)(x+1,y+1)。
一开始卡丁车朝上位于某个平地格子处,其初始移动速率为 v=0v=0。接下来玩家将依次输入 qq 条操作指令,每条操作指令是下列中的一种:
- "L":卡丁车朝向往左转 4545 度。
- "R":卡丁车朝向往右转 4545 度。
- "U":卡丁车的速率由 vv 增大至 v+1v+1。
- "D":卡丁车的速率由 vv 减小至 \max(v-1,0)max(v−1,0)。
在执行完每条操作指令后,卡丁车都会沿着其朝向前进 vv 步,在移动结束后才会继续响应后续指令。在前进的过程中,如果某一步尝试驶入某个障碍格子或者尝试驶出地图,那么说明卡丁车发生了碰撞,它将就此结束移动,在保持朝向的同时速率 vv 降低为 00。特别要注意的是,当朝向是斜4545度时,为了防止"穿模"现象的发生,如果卡丁车两侧都是障碍,那么卡丁车同样将被认为发生了碰撞。例如卡丁车朝向右下,现在将从 (x,y)(x,y) 移动到 (x+1,y+1)(x+1,y+1),那么如果 (x+1,y)(x+1,y) 和 (x,y+1)(x,y+1) 都是障碍,则卡丁车发生了碰撞。
请写一个程序,在执行完每条操作指令后且卡丁车完成移动之后,汇报卡丁车的坐标以及这次移动过程中是否发生了碰撞。
Input第一行包含两个正整数 nn 和 mm (1\leq n,m\leq 501≤n,m≤50),表示地图的尺寸。
接下来 nn 行,第 ii 行包含一个长度为 mm 的字符串,其中第 jj 个字符描述格子 (i,j)(i,j)。如果它是".",则说明 (i,j)(i,j) 是平地;如果它是"#",则说明 (i,j)(i,j) 是障碍;如果它是"*",则说明 (i,j)(i,j) 是平地,且卡丁车位于此。输入数据保证存在恰好一个"*"。
接下来一行包含一个正整数 qq (1\leq q\leq 5001≤q≤500),表示指令的数量。
接下来一行包含一个长度为 qq 的字符串,每个字符是四种指令中的一种,依次描述每条指令。
Output输出 qq 行,第 ii 行输出执行完第 ii 条指令且卡丁车完成移动之后的相关信息。如果这一次卡丁车没有发生碰撞,那么输出"x y";如果这一次卡丁车发生了碰撞,那么输出"Crash! x y"。其中 xx 和 yy 表示卡丁车的坐标为 (x,y)(x,y)。
ExamplesInput5 4 .... ##.. ..#. .*.. .... 12 URULLULLLLUD
Output3 2 Crash! 3 2 Crash! 3 2 3 2 3 2 Crash! 3 2 3 2 3 2 3 2 3 2 4 3 4 3
Input10 10 ####....## ##.......# #....##... #...####.. #...####.. #...####.. #......... #...####.. ....####.. *...####.. 16 UURUURRULUULLUUD
Output9 1 Crash! 9 1 9 1 8 2 6 4 Crash! 6 4 6 4 7 5 7 6 7 8 Crash! 7 10 7 10 7 10 6 10 4 10 3 10
- 思路
模拟题,注意不要倒车入库就行 - 代码
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> using namespace std; int x,y,v,d,nn; int n,m; int map[55][55]; bool crash(int d) { if(d==1) { if(map[x-1][y]&&map[x][y+1]) return 1; } else if(d==3) { if(map[x+1][y]&&map[x][y+1]) return 1; } else if(d==5) { if(map[x+1][y]&&map[x][y-1]) return 1; } else if(d==7) { if(map[x-1][y]&&map[x][y-1]) return 1; } return 0; } int main() { scanf("%d%d",&n,&m); char c,op; v=0;d=0; getchar(); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%c",&c); switch (c) { case '*': x=i;y=j; case '.': map[i][j]=0; break; case '#': map[i][j]=1; break; } } getchar(); } scanf("%d",&nn); getchar(); for(int i=1;i<=nn;i++){ scanf("%c",&op); switch (op) { case 'L': d=(d-1+8)%8; break; case 'R': d=(d+1+8)%8; break; case 'U': v=v+1; break; case 'D': v=max(v-1,0); break; } int xx,yy,xi,yi; switch (d) { case 0: xi=-1,yi=0; break; case 1: xi=-1,yi=1; break; case 2: xi=0,yi=1; break; case 3: xi=1,yi=1; break; case 4: xi=1,yi=0; break; case 5: xi=1,yi=-1; break; case 6: xi=0,yi=-1; break; case 7: xi=-1,yi=-1; break; } int flag=1; for(int i=1;i<=v;i++) { xx=x+xi; yy=y+yi; if(map[xx][yy]==1||xx<=0||yy<=0||xx>n||yy>m||crash(d)) { printf("Crash! %d %d\n",x,y); v=0; flag=0; break; } else x=xx,y=yy; } if(flag) { printf("%d %d\n",x,y); } } return 0; }