Phillip and Trains
思路
读了一个假题,一开始我以为有四种走法,上,下,不动,右。然后直接wa我3次,,,,
题意是,人物先向右移动一格,然后可以选择向前,向后,或者不动,人物移动完之后,火车会向左移动两格。
可以理解为,人物先向右移动一格,然后选择向前,向后或者不动,进而再向右移动两格,在任意时刻都要保证人物不能与火车相撞。
接着就是简单的bfs了, 判断是否可以走当前一步时要注意,一定要判断其路径上的每一个点都是可以移动的。
代码
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
typedef pair<int, int> PII;
const int ax[3] = {-1, 0, 1};
const int ay[4] = {1, 1, 1};
const int N = 110;
int maze[3][N], n, k;
bool judge(int x, int y, int k) {
if(k == 0 && (maze[x][y + 1] || maze[x - 1][y + 1])) return false;
if(k == 1 && (maze[x][y + 1])) return false;
if(k == 2 && (maze[x][y + 1] || maze[x + 1][y + 1])) return false;
return true;
}
bool bfs(int x, int y) {
maze[x][y] = 1;
queue<PII> q;
q.push(mp(x, y));
while(!q.empty()) {
PII temp = q.front();
// cout << temp.first << " " << temp.second << endl;
q.pop();
if(temp.second >= n - 1) return true;
for(int i = 0; i < 3; i++) {
int tempx = temp.first + ax[i];
int tempy = temp.second + ay[i];
if(tempx >= 3 || tempx < 0) continue;
// cout << i << endl;
if(judge(temp.first, temp.second, i)) {
if(maze[tempx][tempy + 1] || maze[tempx][tempy + 2]) continue;
tempy += 2;
// cout << i << endl;
q.push(mp(tempx, tempy));
maze[tempx][tempy] = 1;
}
}
}
return false;
}
int main() {
// freopen("in.txt", "r", stdin);
int t;
scanf("%d", &t);
while(t--) {
memset(maze, 0, sizeof maze);
scanf("%d %d", &n, &k);
int x, y;
char c;
for(int i = 0; i < 3; i++) {
getchar();
for(int j = 0; j < n; j++) {
scanf("%c", &c);
if(c >= 'A' && c <= 'Z')
maze[i][j] = 1;
if(c == 's')
x = i, y = j;
}
}
// for(int i = 0; i < 3; i++)
// for(int j = 0; j < n; j++)
// printf("%d%c", maze[i][j], j + 1 == n ? '\n' : ' ');
if(bfs(x, y)) puts("YES");
else puts("NO");
}
return 0;
}