Title

CF1898C Colorful Grid 题解

题目大意

已知有一个 nm 列的网格图,如下:

现在规定一条可行路为一个点集 p1,p2,,pk,其中,p1 为点 (1,1)pk 为点 (n,m),相邻的两个点 pipi+1 之间的距离为 1,我们规定两个点之间的距离为 |x1x2|+|y1+y2|。你需要对所有的边染成 RB 这两种颜色,使得存在一条长度为 k+1 的可行路(点集的大小为 k+1)满足路径上任意相邻的两条边的颜色不同,一个点(包括 (1,1)(n,m))可以经过多次,如果不存在一种合法方案,输出 NO,否则输出 YES,并输出解决方案。

解题思路

很简单的一道模拟题,容易发现,最短路径的边长度之和为 n+m2,那么相对于最短路而言,一条长度为 k+1 的可行路的边长之和多了 res=k(n+m2)。很显然,任意一条路径不可能短于最短路,若 res<0 直接输出 NO 即可。读者自己模拟以下就可以发现,不存在 res 为奇数的情况,那么若 res 为奇数,直接输出 NO,剩余情况易证均存在一个合法的方案。

我们发现,如果走一格的上半部分,那么会多出 2 的长度,如图:

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

那么,我们可以考虑,如果 resmod4=0,那么直接在终点处走 res4 圈即可,否则的话,那么我们先从上方走最后一格,增加 2 的长度,然后走 res24 圈即可。

注意事项

注意题目中要求的输出格式以及走的顺序。

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 @   UncleSam_Died  阅读(8)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示