记录编号 78089 评测结果 AAAAAAAAAA
题目名称 素数方阵 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 5.525 s
提交时间 2013-11-03 10:34:05 内存使用 14.62 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cstring>
#include<set>
using namespace std;
const int SIZEN=150000;
int isprime[SIZEN]={0};//若为素数则值为true
int digit_sum;
class MAT{
public:
	int s[6][6];
};
bool operator < (MAT a,MAT b){
	int i,j;
	for(i=1;i<=5;i++){
		for(j=1;j<=5;j++){
			if(a.s[i][j]<b.s[i][j]) return true;
			if(a.s[i][j]>b.s[i][j]) return false;
		}
	}
	return false;
}
set<MAT> ans;
class NODE{
public:
	int data;
	int son[10];//加上0~9的10个子节点分别的下标
	bool flag;//子树中是否有素数
	int exs[11];//储存子节点的下标
	int exsnum;
	NODE(){
		flag=false;
		data=0;
		memset(son,0,sizeof(son));
		exsnum=0;
	}
	bool maketree(void);
};
NODE trie[SIZEN];
#define root trie[0]
bool NODE::maketree(void){
	if(data>9999){
		flag=isprime[data];
		son[1]=1;
		return flag;
	}
	int i,sonpos,temp;
	for(i=0;i<=9;i++){
		temp=data*10+i;
		if(temp==data) continue;
		sonpos=temp;
		trie[sonpos].data=temp;
		if(trie[sonpos].maketree()){
			flag=true;
			son[i]=sonpos;
			exs[++exsnum]=i;
		}
	}
	return flag;
}
int getdig(int x){
	int sum=0;
	while(x) sum+=(x%10),x/=10;
	return sum;
}
void getprime(void){
	int i,j;
	int high=(int)sqrt((double)99999);
	for(i=2;i<=high;i++){
		if(!isprime[i]){
			for(j=i*i;j<=99999;j+=i) isprime[j]=true;
		}
	}
	for(i=1;i<10000;i++) isprime[i]=false;
	for(i=10000;i<=99999;i++){
		isprime[i]=!isprime[i];
		if(isprime[i]){
			if(getdig(i)!=digit_sum) isprime[i]=false;
		}
	}
}
int board[6][6]={0};
int decline,decrow;
void print(int board[6][6]){
	int i,j;
	for(i=1;i<=5;i++){
		for(j=1;j<=5;j++) printf("%d ",board[i][j]);
		printf("\n");
	}
	printf("\n");
}
void addmat(void){
	MAT temp;
	int i,j;
	for(i=1;i<=5;i++){
		for(j=1;j<=5;j++) temp.s[i][j]=board[i][j];
	}
	ans.insert(temp);
}
void DFS_line(int x,int y,int z);
void DFS_row(int,int,int);
void check_legal(void){
	int i,x;
	x=0;
	for(i=1;i<=5;i++) x=x*10+board[i][i];
	if(!isprime[x]) return;
	x=0;
	for(i=1;i<=5;i++) x=x*10+board[6-i][i];
	if(!isprime[x]) return;
	addmat();
}
void DFS_line(int x,int k,int nowpos){//第x行,并且前k-1个已先行枚举
	if(x==6) return;
	if(k==6){
		if(x==5) check_legal();
		else{
			int p=0,i;
			for(i=1;i<=x;i++){
				p=trie[p].son[board[i][x]];
			}
			DFS_row(x,x+1,p);
		}
		return;
	}
	int i;
	NODE& now=trie[nowpos];
	int j,temp=0;
	for(j=1;j<x;j++) temp*=10,temp+=board[j][k];
	int v;
	for(i=1;i<=now.exsnum;i++){
		v=now.exs[i];
		if((x==1||k==1)&&v==0) continue;
		if(!trie[temp].son[v]) continue;
		board[x][k]=v;
		DFS_line(x,k+1,now.son[v]);
	}
}
void DFS_row(int x,int k,int nowpos){//第x列,并且前k-1个已先行求出
	if(x==6) return;
	if(k==6){
		int p=0;
		for(int i=1;i<=x;i++){
			p=trie[p].son[board[x+1][i]];
		}
		DFS_line(x+1,x+1,p);
		return;
	}
	int i;
	NODE& now=trie[nowpos];
	int j,temp=0;
	for(j=1;j<x;j++) temp*=10,temp+=board[k][j];
	int v;
	for(i=1;i<=now.exsnum;i++){
		v=now.exs[i];
		if((x==1||k==1)&&v==0) continue;
		if(!trie[temp].son[v]) continue;
		board[k][x]=v;
		DFS_row(x,k+1,now.son[v]);
	}
}
void answer(void){
	set<MAT>::iterator key;
	for(key=ans.begin();key!=ans.end();key++){
		int i,j;
		for(i=1;i<=5;i++){
			for(j=1;j<=5;j++){
				printf("%d",key->s[i][j]);
			}
			printf("\n");
		}
		printf("\n");
	}
}
int main(){
	freopen("prime3.in","r",stdin);
	freopen("prime3.out","w",stdout);
	cin>>digit_sum;
	cin>>board[1][1];
	getprime();
	root.maketree();
	decline=0,decrow=0;
	DFS_line(1,2,root.son[board[1][1]]);
	answer();
	return 0;
}