noip1997 填数字 (搜索)

A1111. 填数字
时间限制: 1.0s   内存限制: 256.0MB  
总提交次数: 550   AC次数: 180   平均分: 63.89
将本题分享到:
       
   
试题来源
  NOIP1997 提高组
问题描述


  如果有多组解,则输出字典序最小的一组。如果无解,输出NO。
输入格式
  第一行一个数n
输出格式
  无解输出NO,否则输出n行每行n个数表示字典序最小的方案。
样例输入
2
样例输出
1 2
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;
}



    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值