题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6313
其实是一个组合构造问题了……
当 为素数,最多可以染黑 个格子且没有四个顶点都被染黑的矩形。
构造:
对于第 行, 列的格子,若 则染黑该格子。
结论、证明以及构造请看知乎上大佬的回答~
https://www.zhihu.com/question/265291665
然而一开始天真的我想取p=44,n=1936,染黑85184个格子……
但是44不是素数诶……
所以其实取p=47,n=2000就可以了w
AC代码:
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string.h>
#include<map>
using namespace std;
int m[2005][2005]={0};
int main()
{
int n=2000;
printf("%d\n",n);
//int cnt=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int a=(i+1)/47,b=(i+1)%47,c=(j+1)/47,d=(j+1)%47;
if(d%47==((c+1)*(a+1)+b)%47)
{
m[i][j]=1;
}
}
}
//printf("%d\n",cnt);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
printf("%d",m[i][j]);
}
printf("\n");
}
}
附上检验代码:(代码风格不一样是因为是队友写的)
ok=0表示没有矩形,ans表示1的个数。
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string.h>
#include<map>
using namespace std;
int arr[2050][2050]={0};
int coun[2010][2010];
int main()
{
/*int n=2000;
printf("%d\n",n);
//int cnt=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int a=(i)/47,b=(i)%47,c=(j)/47,d=(j)%47;
if(d%47==((c+1)*(a+1)+b)%47)
{
arr[i][j]=1;
}
}
}*/
//此处插入矩阵生成代码~
int ok=0,ans=0;
for (int i=0;i<n;i++)
{
for (int j=0;j<n;j++)
{
if (arr[i][j])
{
ans++;
for (int k=i+1;k<n;k++)
{
if (arr[k][j])
{
coun[min(k,i)][max(k,i)]++;
if (coun[min(k,i)][max(k,i)]>1) ok=1;
}
}
}
}
}
printf("%d %d\n",ok,ans);
}