ARC149C (構造)

wuhupai發表於2024-04-01

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

相關文章