原题
题目描述
样例
输入
2
2 3
2 5
输入
1 2
3 1
3 2
1 3
2 1
2 3
-1
思路
首先,我们考虑不合法的情况。
若
,则是一个
的环,每涂上一个颜色就是一行或一列,肯定不合法。
若
,则只有一种颜色,每一行和每一列和每一个环都是同种颜色,肯定不合法。
若
%
,其中
表示边的个数。横着的边有
条,竖着的边也有
条,加起来是
条。
如果这
条边不是
的倍数,则表示每种颜色的个数不可能相等,肯定不合法。
以上都是不合法的情况,剩下的都是合法的。经过反复思考,可以发现一种符合上述要求的填色方法。
首先,遍历一下每一排的正方形,然后,再把它们的上面的边染色,接着,把它们的左右两条边染色。每次染完色后,换一种颜色染。
最后会剩下最后一排的正方形的下面一条边,再将它们如上述方法染色即可。
代码
#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;
}