A1111. 填数字
时间限制:
1.0s 内存限制:
256.0MB
试题来源
NOIP1997 提高组
问题描述
如果有多组解,则输出字典序最小的一组。如果无解,输出NO。
输入格式
第一行一个数n
输出格式
无解输出NO,否则输出n行每行n个数表示字典序最小的方案。
样例输入
2
样例输出
1 2
4 3
4 3
数据规模和约定
1<=n<=10
解析:预处理100以内的素数,然后直接搜索就好。
代码:
#include<cstdio>
#include<cstdlib>
#define maxn 100
using std::exit;
int n,s,a[20][20];
bool flag[maxn*2+10],f[maxn+10];
void redirect()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
}
void operate_prime()
{
int i,j,k;
for(i=2;i<=200;i++)
if(!flag[i])for(j=i+i;j<=200;j+=i)
flag[j]=1;
}
void write_ans()
{
int i,j,k;
for(i=1;i<=n;i++)
{
for(j=1;j<n;j++)printf("%d ",a[i][j]);
printf("%d\n",a[i][n]);
}
}
inline bool ok(int x,int y,int k)
{
if(f[k])return 0;
if(x-1>0 && flag[a[x-1][y]+k])return 0;
if(y-1>0 && flag[a[x][y-1]+k])return 0;
return 1;
}
void dfs(int x,int y)
{
if(x==n && y==n)
{
write_ans();
exit(0);
}
if(y+1<=n)
{
for(int i=2;i<=s;i++)
if(ok(x,y+1,i))a[x][y+1]=i,f[i]=1,dfs(x,y+1),f[i]=0;
}
else
for(int i=2;i<=s;i++)
if(ok(x+1,1,i))a[x+1][1]=i,f[i]=1,dfs(x+1,1),f[i]=0;
}
void work()
{
operate_prime();
scanf("%d",&n);
s=n*n;
a[1][1]=1,f[1]=1;
dfs(1,1);
printf("NO\n");
}
int main()
{
//redirect();
work();
return 0;
}