您的位置:首页 > 其它

4.3.2 The Primes

2014-05-19 21:01 218 查看
/*
ID: daniel.20
LANG: JAVA
TASK: prime3
*/
import java.util.*;
import java.io.*;
import java.math.BigInteger;
class problem2{
StringBuilder sb = new StringBuilder();
long start = System.currentTimeMillis();
boolean primes[] = new boolean[100000];
ArrayList<Integer> arr[] = new ArrayList[50];
int sum=0;
int s=0;
int result[][] = new int[5][5];
int head_table[][];
int cnt =0;
int factor[] = {10000,1000,100,10,1};
ArrayList<String> resultlist = new ArrayList<String>();
void solver() throws IOException{
prime_table();
BufferedReader reader = new BufferedReader(new FileReader("prime3.in"));
StringTokenizer st = new StringTokenizer(reader.readLine());
sum = Integer.valueOf(st.nextToken());
s = Integer.valueOf(st.nextToken());
ArrayList<Integer> t = arr[sum];
head_table = new int[10][t.size()+2];
for(int i=0;i<t.size();i++){
int tmp = t.get(i)/10000;
head_table[tmp][++head_table[tmp][0]] = t.get(i);
}
dfs2(1,s);
if(cnt==0) sb.append("NONE\n");
Collections.sort(resultlist);
for(int i=0;i<resultlist.size();i++){
String tts = resultlist.get(i);
for(int j=0;j<25;j++){
sb.append(tts.charAt(j));
if((j+1)%5==0) sb.append("\n");
}
if(i!=resultlist.size()-1)sb.append("\n");
}
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("prime3.out")));
System.out.print(sb.toString());
pw.print(sb.toString());
pw.close();
System.out.println("$:"+(System.currentTimeMillis()-start));
System.exit(0);
}

void dfs2(int level, int num){
int size = head_table[num][0];
if(level<5){
for(int i=1;i<=size;i++){
int tmp = head_table[num][i];
if(level==1){
boolean flag = true;
for(int j=0;j<factor.length;j++){
int xxx = tmp/factor[j]%10;
if(xxx==0){
flag = false;
break;
}
result[0][j]=xxx;
}
if(flag) dfs2(2, num);
for(int j=0;j<factor.length;j++){
result[0][j]=0;
}
}
else if(level==2){
boolean flag = true;
for(int j=0;j<factor.length;j++){
int xxx = tmp/factor[j]%10;
if(xxx==0){
flag = false;
break;
}
result[j][0]=xxx;
}
if(result[0][4]+result[4][0]>=sum) continue;
if(flag) dfs2(3, result[4][0]);
for(int j=1;j<factor.length;j++){
result[j][0]=0;
}
}
else if(level==3){
boolean flag = true;
for(int j=0;j<factor.length;j++){
int xxx = tmp/factor[j]%10;
if(xxx%2==0||xxx%5==0){
flag = false;
break;
}
result[4][j]=xxx;
}
if(flag) dfs2(4, result[0][4]);
for(int j=1;j<factor.length;j++){
result[4][j]=0;
}
}
else if(level==4){
boolean flag = true;
for(int j=1;j<factor.length-1;j++){
int xxx = tmp/factor[j]%10;
if(xxx%2==0||xxx%5==0){
flag = false;
break;
}
result[j][4]=xxx;
}
if(tmp/10000%10!=result[0][4]||tmp/1%10!=result[4][4]){
flag=false;
}
if(flag) {
result[2][2] = get_num();
if(result[2][2]<0){
result[2][2]=0;
break;
}
if(result[2][2]>=10){
result[2][2]=0;
continue;
}
dfs2(5, result[0][4]);
}
for(int j=1;j<factor.length-1;j++){
result[j][4]=0;
}
}
}
}else{
for(int i=0;i<10;i++){
result[1][1] = i;
result[3][3] = sum-result[0][0]-result[1][1]-result[2][2]-result[4][4];
int k = 10000*result[0][0]+1000*result[1][1]+100*result[2][2]+10*result[3][3]+result[4][4];
if(result[3][3]<0){
result[1][1] = 0;
result[3][3] = 0;
break;
}
if(result[3][3]>=10||!primes[k]) {
result[1][1] = 0;
result[3][3] = 0;
continue;
}
for(int j=0;j<10;j++){
result[3][1] = j;
result[1][3] = sum-result[0][4]-result[3][1]-result[2][2]-result[4][0];
k = 10000*result[4][0]+1000*result[3][1]+100*result[2][2]+10*result[1][3]+result[0][4];
if(result[1][3]<0){
result[3][1] = 0;
result[1][3] = 0;
break;
}
if(result[1][3]>=10||!primes[k]) {
result[3][1] = 0;
result[1][3] = 0;
continue;
}
result[1][2] = sum-result[1][0]-result[1][1]-result[1][3]-result[1][4];
result[3][2] = sum-result[3][0]-result[3][1]-result[3][3]-result[3][4];
result[2][1] = sum-result[0][1]-result[1][1]-result[3][1]-result[4][1];
result[2][3] = sum-result[0][3]-result[1][3]-result[3][3]-result[4][3];

if(result[1][2]<0||result[3][2]<0||result[2][1]<0||result[2][3]<0||result[1][2]>=10||result[3][2]>=10||result[2][1]>=10||result[2][3]>=10){
result[1][2]=0;result[3][2]=0;result[2][1]=0;result[2][3]=0;
result[3][1] = 0;
result[1][3] = 0;
continue;
}
if(is_prime_table()){
String kx = "";
for(int ii=0;ii<5;ii++){
for(int jj=0;jj<5;jj++){
kx+=result[ii][jj];
}
}
resultlist.add(kx);
cnt++;
}
result[1][2]=0;result[3][2]=0;result[2][1]=0;result[2][3]=0;
result[3][1] = 0;
result[1][3] = 0;
}
result[1][1] = 0;
result[3][3] = 0;
}
}
}
int get_num(){
int t1 = sum-result[1][0]-result[1][4];
int t3 = sum-result[3][0]-result[3][4];
int c1 = sum-result[0][2]-result[4][2];
int dig_1 = sum - result[0][0]-result[4][4];
int dig_2 = sum - result[0][4]-result[4][0];
return (dig_1+dig_2+c1 - t1-t3)/3;
}
boolean is_prime_table(){
for(int i=1;i<=3;i++){
int a = 0; int x= 0;
for(int j=0;j<5;j++){
a*=10;
a+=result[j][i];
x+=result[j][i];
}
if(x!=sum) return false;
if(!primes[a]) return false;
}
for(int i=1;i<=3;i++){
int a = 0; int x= 0;
for(int j=0;j<5;j++){
a*=10;
a+=result[i][j];
x+=result[i][j];
}
if(x!=sum) return false;
if(!primes[a]) return false;
}
return true;
}
void prime_table(){
for(int i=0;i<50;i++){
arr[i] = new ArrayList<Integer>();
}
for(int i=10000;i<100000;i++){
if(is_prime(i)){
primes[i]=true;
int tmp = 0;
int temp=i;
while(temp/10>0){
tmp+=temp%10;
temp/=10;
}
tmp+=temp;
arr[tmp].add(i);
}
}
}
boolean is_prime(int a){
for(int i=2;i<=Math.sqrt(a);i++){
if(a%i==0) return false;
}
return true;
}
}
public class prime3 {
public static void main(String[] args) throws Exception {
problem2 p = new problem2();
p.solver();
}
}

这个题目有很多写法,有按边枚举的,也有把25个点一个个枚举的。

其实最重要的是对复杂度的估计,比如以3开头的有100个,然后估算复杂度,才能得出最优枚举边的方案。

最开始做得不好,对复杂度的估算太差了。。。

这个写法参考了一点他人的思路,其实就是先枚举正方形外围四条边,上边和左边不能含0,右边和下边不能含2和5.

汗,开始漏掉了5,复杂度居然提高了3倍。。。

然后有一点很关键,我没想到,在这个情况下正中间那个点是可以直接算出来的!然后再枚举剩下8个点中的2个就行了。

250行的代码。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: