CodeForces 586D
题意略。
将人的移动分为3步,第一步向右,第二步是行之间的变换,第三步是向右走2步,三步加在一起算作是一次移动,计入判重数组。
在第一步时有一个特殊情况:已经越过最右边的边界线,这时graph[x][y] != '.',要进行特判。
在第二步时要注意越界和撞上火车。
在第三步时有3种情况:
1.只需走1步就可以到达边界线。此时,我需要特判。
2.走2步才能到达边界线。注意graph[x][y + 1]不能是火车。
3.不能到达边界线。注意graph[x][y + 1]和graph[x][y + 2]不能是火车。
至于为什么wa这么多次,应该是我没有考虑走路的连贯性,在棋盘上走的时候都是跳跃的。
详见代码:
#include<bits/stdc++.h> #define maxn1 30 #define maxn2 150 using namespace std; char graph[5][maxn2]; int visit[5][maxn2]; int n,k,T; struct point{ int x,y; point(int a = 0,int b = 0){ x = a,y = b; } point operator+ (point p){ return point(p.x + x,p.y + y); } }; bool bfs(point s){ queue<point> que; visit[s.x][s.y] = 1; que.push(s); while(que.size()){ point temp = que.front(); que.pop(); point nxt1 = temp + point(0,1); if(nxt1.y >= n - 1) return true; if(graph[nxt1.x][nxt1.y] != '.') continue; point nxt2; for(int i = -1;i <= 1;++i){ nxt2 = nxt1 + point(i,0); if(nxt2.x < 0 || nxt2.x > 2 || graph[nxt2.x][nxt2.y] != '.') continue; point nxt3 = nxt2 + point(0,2); if(nxt3.y < n - 1 && graph[nxt2.x][nxt2.y + 1] == '.' && graph[nxt2.x][nxt2.y + 2] == '.' && visit[nxt3.x][nxt3.y] == 0){ visit[nxt3.x][nxt3.y] = 1; que.push(nxt3); } else if(nxt2.y + 1 >= n - 1 && visit[nxt3.x][nxt3.y] == 0){ visit[nxt3.x][nxt3.y] = 1; que.push(nxt3); } else if(nxt3.y >= n - 1 && graph[nxt2.x][nxt2.y + 1] == '.' && visit[nxt3.x][nxt3.y] == 0){ visit[nxt3.x][nxt3.y] = 1; que.push(nxt3); } } } return false; } int main(){ scanf("%d",&T); while(T--){ memset(visit,0,sizeof(visit)); scanf("%d%d",&n,&k); point start; for(int i = 0;i < 3;++i){ scanf("%s",graph[i]); if(graph[i][0] == 's'){ start = point(i,0); graph[i][0] = '.'; } } printf("%s\n",bfs(start) ? "YES" : "NO"); } return 0; }