给n*n的网格图的边染k种色,每种色染的边数相同,构造不存在同色环及整行整列不同色的方案
题解:构造题,牛客看到的很强的一个做法:
先特判无解的情况,n = 1,k = 1或 k∤2n(n+1)。(这里忘了n=1无解wa了)
只需要保证同行 / 列没有两条相邻的边,且相邻两行 / 列同一列 / 行的边颜色不相同。
这是很好构造的,对于 k∤n,直接按 1,2,…,k 顺序依次分配边权;对于 k∣n,在偶数行 / 列上循环移 1 位即可(每次错开一位也可)。
1 2 3 1 2 3 或者 1 2 3 1 2 3
2 3 1 2 3 1 2 3 1 2 3 1
1 2 3 1 2 3 3 1 2 3 1 2
时间复杂度是 O(n2)。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 int t; 8 void init(){ 9 int n,k; 10 scanf("%d%d",&n,&k); 11 if (n==1 || (2*(n+1)*n)%k!=0 || k==1){ 12 printf("-1\n"); 13 return; 14 } 15 int temp=0; 16 if (n%k==0){ 17 for (int i=1;i<=2*(n+1);i++){ 18 for (int j=1;j<=n;j++){ 19 temp=temp%k+1; 20 printf("%d ",temp); 21 } 22 printf("\n"); 23 temp=temp%k+1; 24 } 25 return; 26 } 27 for (int i=1;i<=2*(n+1);i++){ 28 for (int j=1;j<=n;j++){ 29 temp=temp%k+1; 30 printf("%d ",temp); 31 } 32 printf("\n"); 33 } 34 } 35 int main(){ 36 scanf("%d",&t); 37 while (t--){ 38 init(); 39 } 40 return 0; 41 }