题目背景
此题约为NOIP提高组Day1T1难度。
题目描述
B君站在一个n*n
的棋盘上。最开始,B君站在(1,1)
这个点,他要走到(n,n)
这个点。
B君每秒可以向上下左右的某个方向移动一格,但是很不妙,C君打算阻止B君的计划。
每秒结束的时刻,C君会在(x,y)
上摆一个路障。B君不能走在路障上。
B君拿到了C君准备在哪些点放置路障。所以现在你需要判断,B君能否成功走到(n,n)
。
保证不会走到某处,然后被一个路障砸死。
输入输出格式
输入格式:
首先是一个正整数T
,表示数据组数。
对于每一组数据:
第一行,一个正整数n
。
接下来2n-2
行,每行两个正整数x
和y
,意义是在那一秒结束后,(x,y)
将被摆上路障。
输出格式:
对于每一组数据,输出Yes
或No
,回答B君能否走到(n,n)
。
输入输出样例
说明
样例解释:
以下0
表示能走,x
表示不能走,B
表示B君现在的位置。从左往右表示时间。
Case 1:
0 0 0 0 0 B (已经走到了)
B 0 x B x 0
Case 2:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 x 0 0 0 0 x 0 0 0 0 x 0 0
0 0 0 0 0 0 0 0 0 0 0 0 x 0 0 0 0 x 0 0
B 0 0 0 0 0 B 0 0 0 0 0 B 0 0 0 0 x B 0 ......(B君可以走到终点)
数据规模:
防止骗分,数据保证全部手造。
对于20%
的数据,有n<=3
。
对于60%
的数据,有n<=500
。
对于100%
的数据,有n<=1000
。
对于100%
的数据,有T<=10
。
bfs
#include <cstring> #include <cstdio> #include <queue> #define N 1005 bool vis[N][N]; int T,n,tim[N][N],fx[5]={1,-1,0,0},fy[5]={0,0,-1,1}; struct node {int x,y,t;}; std::queue<node>q; bool bfs(int x,int y) { q.push((node){x,y,0}); for(int nx,ny,nt;!q.empty();) { nx=q.front().x,ny=q.front().y,nt=q.front().t;q.pop(); if(nx==n&&ny==n) return true; for(int i=0;i<4;++i) { int tx=nx+fx[i],ty=ny+fy[i]; if(tx>=1&&tx<=n&&ty>=1&&ty<=n&&(!tim[tx][ty]||tim[tx][ty]>=nt+1)&&!vis[tx][ty]) { vis[tx][ty]=true; q.push((node){tx,ty,nt+1}); } } } return false; } int main(int argc,char *argv[]) { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int x,y,i=1;i<=2*n-2;++i) { scanf("%d%d",&x,&y); tim[x][y]=i; } if(bfs(1,1)) puts("Yes"); else puts("No"); memset(tim,0,sizeof(tim)); memset(vis,false,sizeof(vis)); } return 0; }