标签:时间 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;
}
标签:时间 n+1 数字 freopen ring amp 标记 print names
原文地址:http://www.cnblogs.com/Bear-Child/p/6048097.html