比較有意思的構造題,首先想到要使兩個數相加為合數,可以讓奇數加上奇數,偶數加上偶數,那麼這樣我們可以使一個陣列的上半邊全部為奇數,下半邊全部為偶數。然後考慮臨界。構造題我雖然不是特別會做,但我覺得一個很重要的就是避免過多的討論,這樣的話我們可以在這行列舉相鄰兩個數的和,然後上面遞增排,相鄰差為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;
}