1. 程式人生 > >A1111. 填數字(dfs遍歷模板)

A1111. 填數字(dfs遍歷模板)

 NOIP1997 提高組    http://www.tsinsen.com/Forum/Index.page?gpid=A1316

問題描述



  如果有多組解,則輸出字典序最小的一組。如果無解,輸出NO。

輸入格式

  第一行一個數n

輸出格式

  無解輸出NO,否則輸出n行每行n個數表示字典序最小的方案。

樣例輸入

2

樣例輸出

1 2
4 3

資料規模和約定

  1<=n<=10

思路:dfs遍歷模板

#include<cstdio>
#include<algorithm>
#include<ctime>
#include<iostream>
#include<cmath>
using namespace std;

int visited[100]= {0},a[100];
int primelist[200]= {0};
int n,N;
bool isstop=false;

bool isprime(int x) {
	int y;
	for(y=2; y<=sqrt(x); y++)
		if (x%y==0)
			return false;
	return true;
}
void dfs(int cur) {

	if(cur==N) {
		isstop=true;
	}
	if(isstop) return ;

	for(int j=0; j<N; j++) {

		if(!visited[j]&&!isstop) {
			int row=cur/n;
			int col=cur%n;
			bool rowok=true;
			if(row>0&&!primelist[a[(row-1)*n+col]+j+1]) {
				rowok=false;
			}
			bool colok=true;
			if(col>0&&!primelist[a[cur-1]+j+1]) {
				colok=false;
			}
			if(rowok&&colok) {
				visited[j]=1;
				a[cur]=j+1;
				dfs(cur+1);
				visited[j]=0;
			}

		}
	}

}
int main() {
	for(int i=2; i<200; i++) {
		if(isprime(i)) primelist[i]=1;
	}
	cin>>n;
	N=n*n;
	dfs(0);
	if(isstop&&a[0]==1)
		for(int i=0; i<N; i++) {
			cout<<a[i]<<" ";
			if((i+1)%n==0) cout<<endl;
		}
	else {
		cout<<"NO"<<endl;
	}
}