链接:CF1634C OKEA
题意:将 1 1 1 到 n × k n\times k n×k 的正整数排成 n n n 行 k k k 列,使得每一行 k k k 个数所有子串的平均数都为整数。
题解
先大胆猜一下,要求这么苛刻的话合法的情况一定不多,经推导果然是这样。
要求所有子串的平均数都为整数,其实可以只看相邻两数。要求所有相邻两数平均数为整数,也就是要求它们奇偶性相同(两数之和能够被 2 2 2 整除)。因此我们可以推导出,每一行的数都分别奇偶性相同。
但因为要填的数是连续正整数,奇偶数的数量之间最多只会相差 1 1 1,因此如果在 k > 1 k>1 k>1 的情况下 n n n 不是偶数,就一定无法满足每一行的数都分别奇偶性相同的要求(此时需要的奇偶数数量差为 k k k)。而当 k = 1 k=1 k=1 的时候,或 k > 1 k>1 k>1 但 n n n 是偶数的时候一定有解(后者为什么有解构造一下即可)。
那么来看如何构造。
当 k = 1 k=1 k=1 的时候,可以直接按顺序输出 1 1 1 到 n n n。
而当 k > 1 k>1 k>1 时,由于要求每一行的数都分别奇偶性相同,所以把所有的奇数排成 k 2 \frac{k}{2} 2k 行,所有的偶数排成 k 2 \frac{k}{2} 2k 行。别忘了除了要求相邻两数平均数为整数,还要求连续任意个数平均数都为整数。而直接按顺序排恰好能够满足这个要求:
设连续 b b b 个奇偶性相同的数,开头的数为 a a a,则平均数为:
∑ i = 1 b a + 2 ( i − 1 ) b = a b + b ( b − 1 ) b = a + b − 1 \frac{\sum_{i=1}^{b}a+2(i-1)}{b}=\frac{ab+b(b-1)}{b}=a+b-1 b∑i=1ba+2(i−1)=bab+b(b−1)=a+b−1
可以证明其为整数。
综上,对输入分类讨论即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
int t,n,k;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
if(n%2&&k>1){
puts("NO");
continue;
}
else{
puts("YES");
if(k==1){
for(int i=1;i<=n;++i)
printf("%d\n",i);
}
else{
int cnt=0;
for(int i=1;i<=n*k;i+=2){
printf("%d",i),cnt++;
if(cnt==k) puts(""),cnt=0;
else printf(" ");
}
for(int i=2;i<=n*k;i+=2){
printf("%d",i),cnt++;
if(cnt==k) puts(""),cnt=0;
else printf(" ");
}
}
}
}
return 0;
}