码迷,mamicode.com
首页 > 编程语言 > 详细

C++ P1187 方格填数

时间:2016-11-09 19:37:57      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:时间   n+1   数字   freopen   ring   amp   标记   print   names   

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

int N,a[15][15],t,moh[]={-1,1,0,0},mol[]={0,0,-1,1};
bool back,u[105],p[105][105];//p用于判断每一个数和那些数字相加是质数;

/*思路:1、n^2-1步;2、第k步走出去以后有n^2-k+1种选择;3、最多验证四次,不合法退格 */

void ans_out()//输出答案;
{
  for(int i=1;i<=N;i++)
  {
    for(int j=1;j<=N;j++) printf("%d ",a[i][j]);
    printf("\n");
  }
  printf("\n");
}

bool is_prime(int x)//判断质数;
{
  if(x<2) return 0;
  int m=(int)sqrt(x+0.5);
  for(int i=2;i<=m;i++) if(x%i==0) return 0;
  return 1;
}

void get_ready()//进行预处理,先判断每个数字和哪些数字相加是质数(一定程度上优化了时间复杂度);
{
  for(int i=1;i<=N*N;i++)
  for(int j=1;j<=N*N;j++)
  {
    if(i==j) continue;
    if(is_prime(i+j)) p[i][j]=1;
  }
}

bool able_to(int x,int y)//辅助判断;
{
  for(int i=0;i<4;i++)
  {
    if(a[x+moh[i]][y+mol[i]]!=0)
      if(!( p[a[x][y]][a[x+moh[i]][y+mol[i]]] )) return 0;
  }
  return 1;
}

void DFS(int x,int y)//实现每一位的尝试;
{
  if(x==N+1) if(++t<=3)
  {
    ans_out();
    if(t==3) back=1;//做标记,及时退出;
    return;
  }
  for(int i=2;i<=N*N;i++)
  {
    if(u[i]) continue;
    a[x][y]=i;
    if(able_to(x,y))
    {
      u[i]=1;
      if(y==N){DFS(x+1,1);if(back) return;}
      else{DFS(x,y+1);if(back) return;}
      u[i]=0;
    }
    a[x][y]=0;
  }
}

int main()
{
  // freopen("test.in","r",stdin);
  // freopen("test.out","w",stdout);
  u[1]=a[1][1]=1;
  scanf("%d",&N);
  get_ready();
  DFS(1,2);
  if(t==0) printf("0");
  return 0;
}

C++ P1187 方格填数

标签:时间   n+1   数字   freopen   ring   amp   标记   print   names   

原文地址:http://www.cnblogs.com/Bear-Child/p/6048097.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!