题目背景:
此题约为NOIP提高组Day1T1难度。
题目描述:
B君站在一个n×nn\times nn×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)
。
样例输入:
2
2
1 1
2 2
5
3 3
3 2
3 1
1 2
1 3
1 4
1 5
2 2
样例输出:
Yes
Yes
说明/提示:
样例解释:
以下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
。
AC Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define N 2020
int n,k,map[N][N],a[N],b[N];//map数组是地图,a和b数组是障碍坐标
bool vis[N][N],flag;//vis是标记数组,flag标记变量记录是否能走到(n,n)
int dx[]={0,0,1,-1};//两个方向数组
int dy[]={1,-1,0,0};
struct node {
int x,y,t;
};
queue<node> q;//这里采用C++ STL的队列
bool judge(int x,int y) {
//不越界 and 这个点不是障碍物 and这个点没有走过
if(x>=1&&x<=n&&y>=1&&y<=n&&map[x][y]==0&&vis[x][y]==false) {
return true;
}
return false;
}
void bfs(int x,int y,int t) {
node now,next;
now.x=x;
now.y=y;
now.t=t;
q.push(now);//起点入队
while(!q.empty()) {//循环保证队列不为空
now=q.front();//取出队首元素
q.pop();//弹出队首
if(now.x==n&&now.y==n) {//走到(n,n)
flag=true;//flag修改为true
return ;//直接返回
}
//在那一秒结束后,(x,y)将被摆上路障,所以这里应该是相应的时间-1
map[a[now.t-1]][b[now.t-1]]=1;
for(int i=0;i<4;i++) {//四个方向搜索
int tx=now.x+dx[i];
int ty=now.y+dy[i];
if(judge(tx,ty)) {//合法判断
vis[tx][ty]=true;//标记该点
next.x=tx;
next.y=ty;
next.t=now.t+1;//时间+1
q.push(next);//入队
}
}
}
}
int main() {
scanf("%d",&k);
while(k--) {
scanf("%d",&n);
for(int i=1;i<=2*n-2;i++) {
scanf("%d %d",&a[i],&b[i]);
}
flag=false;
memset(vis,false,sizeof(vis));//标记数组清零
memset(map,0,sizeof(map));//地图全部初始化为0
vis[1][1]=true;//标记起点
bfs(1,1,0);
if(flag) {//到达(n,n)
printf("Yes\n");
}else {//无法到达
printf("No\n");
}
}
return 0;
}