题目链接:哆啦A梦传送门
题意:构造一个图,满足任意一个子矩形中其四角不都为1,并且要使得图中1的个数要超过85000个。
参考题解:https://blog.csdn.net/qq_37891604/article/details/81255019
https://blog.csdn.net/LSD20164388/article/details/81214339
这题我们需要构造,举个5*25的例子,构造方法如下:
当我们取质数5时, 1的位置 在 j 上 依次 + 0,1,2,3,4,5...... mod 5 的 意义下
构造第一块:
+0 : 10000 10000 10000 10000 10000
+1 : 10000 01000 00100 00010 00001
+2 : 10000 00100 00001 01000 00010
+3 : 10000 00010 01000 00001 00100
+4 : 10000 00001 00010 00100 01000
接着我们构造第二块:
+0:01000 01000 01000 01000 01000(第一个块1都向右移,mod5)
+1 : 01000 00100 00010 00001 10000
+2 : 01000 00010 01000 00001 00100
+3 : 01000 00001 00010 00100 01000
+4 : 01000 10000 00001 00010 00100
证明:
我们设C1,C2为同一行中数值为1的两列,并设他们在这一行的块号为k1, k2
那么对于(i,j)确定的行,第k1块,有j * k1 + i ≡ C1(mod n)
对于(i,j)确定的行,第k2块,有j * k2 + i ≡ C2(mod n)
得到:j*(k1-k2) ≡ (C1-C2) (mod n)
若n为素数,则方程有唯一解
这样我们便可以解得唯一的(i,j),也就是说不会有两行的C1,C2列都为1,即没有四角都为1的矩阵。
代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=2500;
int res[maxn][maxn];
int main()
{
for(int i=0;i<47;i++) ///第几块
for(int j=0;j<47;j++) ///每一块的第j行
for(int k=0;k<47;k++) ///每一块的第k列(个)为1
res[i*47+j][47*k+(j*k+i)%47]=1;
printf("%d\n",2000);
for(int i=0;i<2000;i++){
for(int j=0;j<2000;j++)
printf("%d",res[i][j]);
puts("");
}
return 0;
}