小明同学 站在一个 n×n 的棋盘上。最开始,小明同学站在 (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
解题时要注意路障是每过一秒后放置,不是一开始就全部放置了路障,即在起步时是没有任何路障,在每一秒末都会放置一个路障,这道题目可以起点(1,1)一步步进行探索,并且由于到达(n,n)点只能从(n-1,n)和(n,n-1)两点到达,所以从末状态反推到达(n,n)点的过程,可知只要该点的左方和上方有一个能够通过就能够到达该点,由此可以得出题目代码为#include<stdio.h>
int f[1001][1001],n,t,x,y;//数组f用来记录路障的的有无
int main()
{
scanf("%d",&t);
for(int q=1;q<=t;q++)//测试数组个数
{
scanf("%d",&n);//路障个数
for(int i=1;i<=2*n-2;i++)
{
scanf("%d%d",&x,&y);
if(x==n&&y==n&&x+y-2<i)//x+y-2<i用来判断在到达该点之前是否会被路障阻拦
{
printf("No\n");
break;
}
if(x+y-2>i)
f[x][y]=-1;
}
f[1][1]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if((f[i-1][j]==1||f[i][j-1]==1)&&f[i][j]!=-1)
f[i][j]=1;//能够到达则赋值为1
if(f[n][n]==1)
printf("Yes\n");
else
printf("No\n");
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
f[i][j]=0;
}
}