题目描述
哎,又是银首,要是你这个签到题少WA一发就金了
牛牛战队的队员打完比赛以后又到了日常甩锅的时间。他们心情悲伤,吃完晚饭以后,大家相约到一个街机厅去solo。牛牛和牛能进入了一个迷宫,这个迷宫里除了墙壁的阻拦,还会有僵尸的阻拦。情况十分复杂,牛能为了更快的追逐牛牛,迅速放出了大招,让牛牛原地眩晕,而眩晕的解药,也只有牛能自己拥有。
这一个迷宫可以简化为一个$n$行$m$列的矩阵,其中有一些僵尸,这些僵尸会在一个$1*k$的矩形中来回游走。他不会攻击眩晕状态下的人,只会攻击和他抢地盘的人。这名队员每次移动需要一个单位时间,而且他不能穿墙,不能和僵尸处于同一位置,在追到另一名队员之前也不能停下来。
在这一场追逐战中,要么牛能追逐成功,取得胜利,要么被僵尸击败,牛牛胜利。那谁会是最终的王者呢?
输入描述:
输入数据有很多行。第一行输入4个整数$n,m,p,k(3leq n,mleq 500,0leq pleq 50,2leq kleq 10)$,分别表示迷宫的行、列,僵尸的数量,僵尸来回走动的长度。
第2行到第$n+1$行输入一个矩阵,每行输入一个字符串,第$i$个字符串的第$j$个字符表示矩阵中第$i$行$j$列的状态,如果字符是#表示是可以走的路,如果是&表示是障碍物,A是被眩晕队员的位置,L是追赶者的位置。
第$n+2$行到第$n+p+1$行每行输入两个整数$x,y$和一个字符串,第$i$行的数据表示第$i$个僵尸当前时间会从第$x$行$y$列出发,沿着固有的方向前进$k$个单位时间后折返,再走回它之前的位置,再折返,依照这种方法循环下去。第三个字符串表示僵尸初始行进的方向,UP表示向上走,LEFT表示向左走,DOWN表示向下走,RIGHT表示向右走。数据保证在$k$个长度内僵尸不会碰到边界或者墙壁。
输出描述:
如果牛能可以追上牛牛,输出一个整数,表示最短追上的时间。否则输出一行Oh no。
输入
4 4 1 2 L#&A ##&# #&## #### 3 3 DOWN
输出
Oh no
说明
初始状态
L#&A
##&#
#&*#
####
一单位时间后
##&A
L#&#
#&##
##*#
二单位时间后
##&A
##&#
L&*#
####
三单位时间后
##&A
##&#
#&##
L#*#
四单位时间后
##&A
##&#
#&*#
#L##
牛能如果再向左走的话就会跟僵尸碰个正着,而且不论牛能怎么往回走,在(4,3)总能遇见僵尸,所以他失败了。
传送门:
https://ac.nowcoder.com/acm/contest/3006/G
思路:
不会搜索的我,只能看题解之后琢磨了。
首先这道题如果没有僵尸的话,就是一道基础的BFS题,但出题人丢给你$p$个僵尸,怎么办呢?
仔细看题中有两个限制条件,$p$个僵尸的步伐一致并且在$1*k$的矩形内来回游走。
当僵尸走的次数为$1,2k+1,3k+1...nk+1$时,僵尸都处在同一位置,也就是说僵尸以$2k$为周期来回走。
所以只要在加一维来记录步数的变化。具体看代码。
代码:
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int n, m, p, k; 6 7 int mod; 8 9 int ax, ay; 10 11 int bx, by; 12 13 14 char s[505][505]; 15 16 bool no[505][505][30]; 17 18 bool vis[505][505]; 19 20 int d[4][2] = {0, 1, 0, -1, -1, 0, 1, 0}; 21 struct node 22 { 23 int x; 24 int y; 25 int d; 26 }; 27 28 queue<node>q; 29 30 int ans; 31 int bfs(int x, int y) 32 { 33 node tmp; 34 tmp.x = x, tmp.y = y, tmp.d = 0; 35 q.push(tmp); 36 vis[x][y] = 1; 37 38 while(q.size()) 39 { 40 node t = q.front(); 41 q.pop(); 42 if(t.x == ax && t.y == ay) 43 return ans = t.d; 44 45 46 for(int i = 0; i < 4; i++) 47 { 48 int xx = t.x + d[i][0]; 49 int yy = t.y + d[i][1]; 50 51 if(xx < 1 || xx > n || yy < 1 || yy > m || no[xx][yy][(t.d + 1) % mod] || s[xx][yy] == '&' || vis[xx][yy]) 52 continue; 53 vis[xx][yy] = 1; 54 tmp.x = xx; 55 tmp.y = yy; 56 tmp.d = t.d + 1; 57 q.push(tmp); 58 } 59 } 60 return -1; 61 } 62 int main() 63 64 { 65 scanf("%d%d%d%d", &n, &m, &p, &k); 66 mod = 2 * k - 2; 67 68 for(int i = 1; i <= n; i++) 69 { 70 scanf("%s", s[i] + 1); 71 for(int j = 1; j <= m; j++) 72 { 73 if(s[i][j] == 'A') 74 { 75 ax = i; 76 ay = j; 77 } 78 else if(s[i][j] == 'L') 79 { 80 bx = i; 81 by = j; 82 } 83 } 84 } 85 86 for(int i = 1; i <= p; i++) 87 { 88 int x, y; 89 char op[10]; 90 scanf("%d %d %s", &x, &y, op); 91 if(op[0] == 'R') 92 { 93 for(int j = 0; j < k; j++) 94 { 95 no[x][y + j][j] = 1; 96 no[x][y + j][((k - 1) * 2 - j) % mod] = 1; 97 } 98 } 99 else if(op[0] == 'L') 100 { 101 for(int j = 0; j < k; j++) 102 { 103 no[x][y - j][j] = 1; 104 no[x][y - j][((k - 1) * 2 - j) % mod] = 1; 105 } 106 } 107 else if(op[0] == 'U') 108 { 109 for(int j = 0; j < k; j++) 110 { 111 no[x - j][y][j] = 1; 112 no[x - j][y][((k - 1) * 2 - j) % mod] = 1; 113 } 114 } 115 else if(op[0] == 'D') 116 { 117 for(int j = 0; j < k; j++) 118 { 119 no[x + j][y][j] = 1; 120 no[x + j][y][((k - 1) * 2 - j) % mod] = 1; 121 } 122 } 123 } 124 if(bfs(bx, by) == -1) 125 { 126 printf("Oh no "); 127 } 128 else 129 { 130 printf("%d ", ans ); 131 } 132 }