比较有意思的构造题,首先想到要使两个数相加为合数,可以让奇数加上奇数,偶数加上偶数,那么这样我们可以使一个数组的上半边全部为奇数,下半边全部为偶数。然后考虑临界。构造题我虽然不是特别会做,但我觉得一个很重要的就是避免过多的讨论,这样的话我们可以在这行枚举相邻两个数的和,然后上面递增排,相邻差为2,下面递减排,相邻差为2。然后对于奇偶分开判断。
对于边长为偶数的情况:然后枚举一个合数,然后枚举一个奇数和一个偶数,递增填即可,剩下随便填。
对于边长为奇数的情况:和上面一样,但是这样如果边长为奇数的时候中间会出现一个阶梯,所以还要枚举这个阶梯是否合法。
放下代码,有点细节,但实现起来花的时间好像没这么多
#include<bits/stdc++.h>
using namespace std;
long long n,gg,gg1,a[1005][1005],cnt1=1,cnt2=2;
bool vis[1000005];
bool check(long long x){
for(long long i=2;i*i<=x;i++){
if(x%i==0) return false;
}
return true;
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n;
if(n%2==0){
for(long long i=2*n+1;;i+=2){
if(!check(i)){
gg=i;
break;
}
}
gg-=(2*n-2);
for(long long i=1;i+2*n-2<=n*n;i+=2){
if((gg-i)+2*n-2<=n*n){
gg1=gg-i;
gg=i;
break;
}
}
for(long long i=1;i<=n;i++){
a[n/2][i]=gg+i*2-2;//odd
a[n/2+1][n-i+1]=gg1+i*2-2;//even
vis[gg+i*2-2]=vis[gg1+(n-i)*2]=true;
}
for(long long i=1;i<=n/2-1;i++){
for(long long j=1;j<=n;j++){
while(vis[cnt1]){
cnt1+=2;
}
vis[cnt1]=true;
a[i][j]=cnt1;
}
}
for(long long i=n/2+2;i<=n;i++){
for(long long j=1;j<=n;j++){
while(vis[cnt2]){
cnt2+=2;
}
vis[cnt2]=true;
a[i][j]=cnt2;
}
}
for(long long i=1;i<=n;i++){
for(long long j=1;j<=n;j++){
cout<<a[i][j]<<" ";
}
cout<<"\n";
}
}else if(n==3){
cout<<"1 3 9\n8 7 5\n6 2 4\n";
}else{
for(long long i=3;;i+=2){
if(!check(i+2*n-2)&&!check(i+2*n)){
gg=i;
break;
}
}//gg
//cout<<gg<<endl;
for(long long i=1;i+2*n-2<=n*n;i+=2){
if((gg-i)+2*n-2<=n*n){
gg1=gg-i;
gg=i;
break;
}
}
//cout<<gg<<" "<<gg1<<endl;
for(long long i=1;i<=n/2;i++){
a[n/2][i]=gg+2*i-2;
vis[gg+2*i-2]=true;
}for(long long i=n/2+1;i<=n;i++){
a[n/2+1][i]=gg+2*i-2;
vis[gg+2*i-2]=true;
}for(long long i=1;i<=n/2+1;i++){
a[n/2+2][n-i+1]=gg1+2*i-2;
vis[gg1+2*i-2]=true;
}for(long long i=n/2+2;i<=n;i++){
a[n/2+1][n-i+1]=gg1+2*i-2;
vis[gg1+2*i-2]=true;
}
for(long long i=1;i<=n/2;i++){
for(long long j=1;j<=n;j++){
if(a[i][j]==0){
while(vis[cnt1]){
cnt1+=2;
}
vis[cnt1]=true;
a[i][j]=cnt1;
}
}
}
for(long long i=n/2+2;i<=n;i++){
for(long long j=1;j<=n;j++){
if(a[i][j]==0){
while(vis[cnt2]){
cnt2+=2;
}
vis[cnt2]=true;
a[i][j]=cnt2;
}
}
}
for(long long i=1;i<=n;i++){
for(long long j=1;j<=n;j++){
cout<<a[i][j]<<" ";
}
cout<<"\n";
}
}
return 0;
}
标签:偶数,gg,奇数,long,ARC149C,枚举,构造,边长
From: https://www.cnblogs.com/wuhupai/p/18109105