Title

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|$。你需要对所有的边染成 RB 这两种颜色,使得存在一条长度为 $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;
}
posted @ 2023-11-24 10:57  UncleSam_Died  阅读(22)  评论(0)    收藏  举报  来源