CF1898C Colorful Grid 题解
题目大意
已知有一个 $n$ 行 $m$ 列的网格图,如下:

现在规定一条可行路为一个点集 $p_1,p_2,\dots,p_k$,其中,$p_1$ 为点 $(1,1)$,$p_k$ 为点 $(n,m)$,相邻的两个点 $p_i$ 和 $p_{i+1}$ 之间的距离为 $1$,我们规定两个点之间的距离为 $|x_1-x_2|+|y_1+y_2|$。你需要对所有的边染成 R 或 B 这两种颜色,使得存在一条长度为 $k+1$ 的可行路(点集的大小为 $k+1$)满足路径上任意相邻的两条边的颜色不同,一个点(包括 $(1,1)$ 和 $(n,m)$)可以经过多次,如果不存在一种合法方案,输出 NO,否则输出 YES,并输出解决方案。
解题思路
很简单的一道模拟题,容易发现,最短路径的边长度之和为 $n+m-2$,那么相对于最短路而言,一条长度为 $k+1$ 的可行路的边长之和多了 $res=k-(n+m-2)$。很显然,任意一条路径不可能短于最短路,若 $res<0$ 直接输出 NO 即可。读者自己模拟以下就可以发现,不存在 $res$ 为奇数的情况,那么若 $res$ 为奇数,直接输出 NO,剩余情况易证均存在一个合法的方案。
我们发现,如果走一格的上半部分,那么会多出 $2$ 的长度,如图:

同样,如果绕一圈,那么会多出 $4$ 的长度,如图:

那么,我们可以考虑,如果 $res\bmod 4=0$,那么直接在终点处走 $\frac{res}{4}$ 圈即可,否则的话,那么我们先从上方走最后一格,增加 $2$ 的长度,然后走 $\frac{res-2}{4}$ 圈即可。
注意事项
注意题目中要求的输出格式以及走的顺序。
AC 代码
码风较丑,不喜勿喷。
#include<math.h>
#include<time.h>
#include<stdio.h>
#include<algorithm>
#define ll long long
#define N 20
int n,m,k;
char map1[N][N];
char map2[N][N];
inline void work(){
scanf("%d%d%d",&n,&m,&k);
int mint=n-1+m-1;
if(k<mint){
puts("No");
return;
}
if((k-mint)&1){
puts("No");
return;
}puts("Yes");
int res=k-mint;
for(register int i=1;i<=n;++i)
for(register int j=1;j<=m;++j)
map1[i][j]=map2[i][j]='R';
int col=0;
if(res%4==0){
for(register int i=1;i<n;++i){
col=col^1;
if(col==1)
map2[i][1]='R';
else map2[i][1]='B';
}
for(register int j=1;j<m;++j){
col=col^1;
if(col==1)
map1[n][j]='R';
else map1[n][j]='B';
}
col=col^1;
if(col==1)
map2[n-1][m]='R';
else map2[n-1][m]='B';
col=col^1;
if(col==1)
map1[n-1][m-1]='R';
else map1[n-1][m-1]='B';
col=col^1;
if(col==1)
map2[n-1][m-1]='R';
else map2[n-1][m-1]='B';
}else{
for(register int i=1;i<n;++i){
col=col^1;
if(col==1)
map2[i][1]='R';
else map2[i][1]='B';
}
for(register int j=1;j<m-1;++j){
col=col^1;
if(col==1)
map1[n][j]='R';
else map1[n][j]='B';
}
col=col^1;
if(col==1)
map2[n-1][m-1]='R';
else map2[n-1][m-1]='B';
col=col^1;
if(col==1)
map1[n-1][m-1]='R';
else map1[n-1][m-1]='B';
col=col^1;
if(col==1)
map2[n-1][m]='R';
else map2[n-1][m]='B';
col=col^1;
if(col==1)
map1[n][m-1]='R';
else map1[n][m-1]='B';
}
for(register int i=1;i<=n;++i){
for(register int j=1;j<m;++j){
if(j!=1) putchar(' ');
putchar(map1[i][j]);
}putchar('\n');
}
for(register int i=1;i<n;++i){
for(register int j=1;j<=m;++j){
if(j!=1) putchar(' ');
putchar(map2[i][j]);
}putchar('\n');
}
}signed main(){
srand(114514);
srand(rand());
srand(time(0));
int T;scanf("%d",&T);
while(T--) work();
return 0;
}

浙公网安备 33010602011771号