USACO 4.3.2 The Primes( 筛法求素数, 搜索)

USACO 4.3.2 The Primes( 筛法求素数, 搜索)
做了一天. AC的速度还可以,  时间最长的 0.16s.

1. 开始做之前,要确定下搜索顺序, 这个很关键.
                      
    参考 http://starforever.blog.hexun.com/2319991_d.html

2. 首先用筛法求出10000 - 99999的所有素数,然后对素数进行分类: 5位数中, 分成第一位是固定的; 第三位是固定的;第一和五位是固定的;第一、二、四位是固定的。注意搜索顺序3、6中,不能有0出现(题意要求)。这样减少枚举的次数。

3. 然后就7层DFS,

4. 最后对搜索结果进行排序,我用的是插入排序。

/**/ /*
ID: lorelei3
TASK: prime3
LANG: C++
*/


#include 
< fstream >
#include 
< iostream >
#include 
< cmath >
#include 
< memory.h >

using   namespace  std;

const   int  MAX  =   99999 ;

const   int  DIV[ 6 =   {0,100001000100101} ;

bool  primes[MAX];

int  n, sum;

int  prime1[ 10 ][ 1000 ][ 6 ];
int  nprime1[ 10 ];

int  prime3[ 10 ][ 1000 ][ 6 ];
int  nprime3[ 10 ];

int  prime15[ 10 ][ 10 ][ 100 ][ 6 ];
int  nprime15[ 10 ][ 10 ];

int  prime124[ 10 ][ 10 ][ 10 ][ 100 ][ 6 ];
int  nprime124[ 10 ][ 10 ][ 10 ];

void  dfs1();
void  dfs2();
void  dfs3();
void  dfs4();
void  dfs5();
void  dfs6();
void  dfs7();

ifstream fin(
" prime3.in " );
ofstream fout(
" prime3.out " );

void  addPrime( int  s) {
    
int i, k=1, tmp[6];
    
int num = s;
    
while(num!=0){
        tmp[k] 
= num/DIV[k];
        num 
= num%DIV[k];
        k
++;
    }

    
int c =0;
    
for(i=1; i<=5++i)
        c 
+= tmp[i];
    
if(c == sum){
        primes[s]
=true;
        
for(i=1; i<=5++i){
            
int t = nprime1[tmp[1]];
            prime1[tmp[
1]][t][i] = tmp[i];
        }

        nprime1[tmp[
1]]++;

        
for(i=1; i<=5++i){
            
int t = nprime3[tmp[3]];
            prime3[tmp[
3]][t][i] = tmp[i];
        }

        nprime3[tmp[
3]]++;

        
bool flag=true;
        
for(i=1; i<=5++i){
            
if(tmp[i]==0){
                flag
=false;
                
break;
            }

            
int t = nprime15[tmp[1]][tmp[5]];
            prime15[tmp[
1]][tmp[5]][t][i] = tmp[i];
        }

        
if(flag)
            nprime15[tmp[
1]][tmp[5]]++;
        
        
for(i=1; i<=5++i){
            
int t = nprime124[tmp[1]][tmp[2]][tmp[4]];
            prime124[tmp[
1]][tmp[2]][tmp[4]][t][i] = tmp[i];
        }

        nprime124[tmp[
1]][tmp[2]][tmp[4]]++;

    }

}


int  map[ 6 ][ 6 ];
int  ans[ 1000 ][ 6 ][ 6 ];
int  cnt = 0 ;

bool  inline larger_than( int  a[ 6 ][ 6 ],  int  b[ 6 ][ 6 ]) {
    
for(int i=1; i<=5++i)
        
for(int j=1; j<=5++j)
            
if(a[i][j]>b[i][j])
                
return true;
            
else if(a[i][j]<b[i][j])
                
return false;
            
else 
                
continue;
    
return false;
}


void  addResult() {
    
int p = ++cnt;
    
while(p!=0 && larger_than(ans[p-1], map)){
        memcpy(ans[p], ans[p
-1], sizeof(int)*36);
        p
--;
    }

    memcpy(ans[p], map, 
sizeof(int)*36);
}


int  isPrime( int  a) {
    
int n = static_cast<int>(sqrt(a));
    
for(int i=2; i<=n; ++i)
        
if(!(a%i))
            
return 0;
    
return 1;
}


int  d = 0 ;
void  initPrime() {
    
for(int i=10001; i<=99999++i)
        
if(isPrime(i))
            addPrime(i);
}


bool  check1( int  r) {
    
int i,sum=0;
    
for(i=1; i<=5++i)
        sum 
= sum*10+map[r][i];
    
    
if(!primes[sum]) return false;

    
return true;
}


bool  check2( int  c) {

    
int i,sum=0;
    
for(i=1; i<=5++i)
        sum 
= sum*10+map[i][c];

    
if(!primes[sum]) return false;
    
    
return true;
}


void  dfs1() {
    
int t = nprime1[map[1][1]];
    
if(t==0)
        
return;
    
else
        
for(int i=0; i<t; ++i){
            
for(int j=2; j<=5++j)
                map[j][j] 
= prime1[map[1][1]][i][j];

            dfs2();
        }

}


void  dfs2() {
    
int t = nprime3[map[3][3]];
    
if(t==0)
        
return;
    
else
        
for(int i=0; i<t; ++i){
            
for(int j=1; j<=5++j)
                map[
6-j][j] = prime3[map[3][3]][i][j];

            dfs3();
        }

}


void  dfs3() {
    
int t = nprime15[map[1][1]][map[1][5]];
    
if(t==0)
        
return;
    
else
        
for(int i=0; i<t; ++i){
            
for(int j=2; j<=4++j)
                map[
1][j] = prime15[map[1][1]][map[1][5]][i][j];

        dfs4();
        }

}


void  dfs4() {
    
int t = nprime124[map[1][2]][map[2][2]][map[4][2]];
    
if(t==0)
        
return;
    
else
        
for(int i=0; i<t; ++i){
            
for(int j=3; j<=5++j)
                map[j][
2= prime124[map[1][2]][map[2][2]][map[4][2]][i][j];

            dfs5();
        }

}


void  dfs5() {
    
int t = nprime124[map[1][4]][map[2][4]][map[4][4]];
    
if(t==0)
        
return;
    
else
        
for(int i=0; i<t; ++i){
            
for(int j=3; j<=5++j)
                map[j][
4= prime124[map[1][4]][map[2][4]][map[4][4]][i][j];

            
for(int k=1; k<=9; k+=2){
                map[
5][3]=k;

                
if(check1(5))
                    dfs6();
            }

        }

}


void  dfs6() {
    
int t = nprime15[map[1][1]][map[5][1]];
    
if(t==0)
        
return;
    
else
        
for(int i=0; i<t; ++i){
            
for(int j=2; j<=4++j)
                map[j][
1= prime15[map[1][1]][map[5][1]][i][j];

            
for(int k=1; k<=9; k+=2){
                map[
3][5= k;

                
if(check1(3))
                    dfs7();
            }

        }

}


void  dfs7() {
    
int t = nprime124[map[2][1]][map[2][2]][map[2][4]];
    
if(t==0)
        
return;
    
else
        
for(int i=0; i<t; ++i){
            
for(int j=3; j<=5++j)
                map[
2][j] = prime124[map[2][1]][map[2][2]][map[2][4]][i][j];

            
for(int a=0; a<=9++a){
                map[
4][3]=a;
                
if(check2(3))
                    
for(int b=1; b<=9; b+=2){
                        map[
4][5= b;

                        
if(check1(4&& check2(5) )
                            addResult();
                    }

            }

        }

}



void  output() {
    
for(int k=0; k<cnt-1++k){
        
for(int i=1; i<=5++i){
            
for(int j=1; j<=5++j)
                fout
<<ans[k][i][j];
            fout
<<endl;
        }

        
if(cnt==1)
            
return;
        fout
<<endl;
    }


    
for(int i=1; i<=5++i){
        
for(int j=1; j<=5++j)
            fout
<<ans[cnt-1][i][j];
        fout
<<endl;
    }

}


int  main() {

    
//input
    fin>>sum>>map[1][1];

    
//init
    for(int i=1; i<=5++i)
        
for(int j=1; j<=5++j)
            ans[
0][i][j] = 9;
    initPrime();

    
//solve
    dfs1();

    
//output
    output();

    
return 0;
}

你可能感兴趣的:(USACO 4.3.2 The Primes( 筛法求素数, 搜索))