2020牛客暑期多校训练营(第六场) Grid Coloring

原题
题目描述
在这里插入图片描述
样例
输入

2
2 3
2 5

输入

1 2
3 1
3 2
1 3
2 1
2 3
-1

思路
首先,我们考虑不合法的情况。
n = 1 n=1 ,则是一个 1 × 1 1×1 的环,每涂上一个颜色就是一行或一列,肯定不合法。
k = 1 k=1 ,则只有一种颜色,每一行和每一列和每一个环都是同种颜色,肯定不合法。
2 n × ( n + 1 ) 2n×(n+1) % k ! = 0 k!=0 ,其中 2 n × ( n + 1 ) 2n×(n+1) 表示边的个数。横着的边有 n × ( n + 1 ) n×(n+1) 条,竖着的边也有 n × ( n + 1 ) n×(n+1) 条,加起来是 n × ( n + 1 ) n×(n+1) 条。
如果这 n × ( n + 1 ) n×(n+1) 条边不是 k k 的倍数,则表示每种颜色的个数不可能相等,肯定不合法。
以上都是不合法的情况,剩下的都是合法的。经过反复思考,可以发现一种符合上述要求的填色方法。
首先,遍历一下每一排的正方形,然后,再把它们的上面的边染色,接着,把它们的左右两条边染色。每次染完色后,换一种颜色染。
最后会剩下最后一排的正方形的下面一条边,再将它们如上述方法染色即可。
代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=205;
int a[maxn][maxn],b[maxn][maxn],t,n,k,sum;
int main()
{
    for(scanf("%d",&t);t--;sum=0)
	{
        scanf("%d%d",&n,&k);
        if(n==1||k==1||(2*n*(n+1))%k){puts("-1");continue;}
        for(int i=0;i<n;i++)//染上正方形的上左右三条边
		{
            for(int j=0;j<n;j++)sum=sum%k+1,a[i][j]=sum;
            for(int j=0;j<=n;j++)sum=sum%k+1,b[j][i]=sum;
            //输出的时候是一列一列输出,而我们是横着遍历的,所以用b[j][i]存储
        }
        for(int i=0;i<n;i++)sum=sum%k+1,a[n][i]=sum;
        //染最后一排正方形的下面的边
        for(int i=0;i<=n;i++)
		{
            for(int j=0;j<n;j++)printf("%d ",a[i][j]);
            printf("\n");
        }
        for(int i=0;i<=n;i++)
		{
            for(int j=0;j<n;j++)printf("%d ",b[i][j]);
            printf("\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/bbbll123/article/details/107639980
今日推荐