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;
	}
}

猜你喜欢

转载自blog.csdn.net/qiang_____0712/article/details/84948451