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