Простые числа
http://acm.pku.edu.cn/JudgeOnline/problem?id=1165

Код:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAXP 1000
#define MAXS 200
typedef struct
{
int d[5]; // decimal digits - for quick lookup
int val; // prime decimal value
} PRIME;
// records for storing primes as "prime patterns"
typedef struct {
int n,r[200];
} RECORD200;
typedef struct {
int n,r[50];
} RECORD50;
typedef struct {
int n,r[20];
} RECORD20;
typedef struct {
char s[5*5+1];
} SOLUTION;
PRIME p[MAXP];
int np;
int prime[10][10][10][10][10];// whether number (given its digits) is prime
int dg_sum; // digit sum
int sq_a,sq_b,sq_c,sq_d,sq_e, // prime square
sq_f,sq_g,sq_h,sq_i,sq_j,
sq_k,sq_l,sq_m,sq_n,sq_o,
sq_p,sq_q,sq_r,sq_s,sq_t,
sq_u,sq_v,sq_w,sq_x,sq_y;
// '.' = unknown, '_' = 1,3,7,9, '-' = non-zero
RECORD200 pat1[10]; // prime pattern #1: X..._
RECORD200 pat2[10]; // prime pattern #2: _.X._
RECORD50 pat3[10][10]; // prime pattern #3: X---Y
RECORD20 pat4[10][10][10]; // prime pattern #4: XY.Z_
RECORD20 pat7[10][10][10]; // prime pattern #7: X.Y.Z
RECORD20 pat8[10][10][10]; // prime pattern #8: .XYZ_
SOLUTION sol[MAXS];
int nsolution;
void solution(void) {
sol[nsolution].s[0] = sq_a; sol[nsolution].s[1] = sq_b;
sol[nsolution].s[2] = sq_c; sol[nsolution].s[3] = sq_d;
sol[nsolution].s[4] = sq_e; sol[nsolution].s[5] = sq_f;
sol[nsolution].s[6] = sq_g; sol[nsolution].s[7] = sq_h;
sol[nsolution].s[8] = sq_i; sol[nsolution].s[9] = sq_j;
sol[nsolution].s[10] = sq_k;sol[nsolution].s[11] = sq_l;
sol[nsolution].s[12] = sq_m;sol[nsolution].s[13] = sq_n;
sol[nsolution].s[14] = sq_o;sol[nsolution].s[15] = sq_p;
sol[nsolution].s[16] = sq_q;sol[nsolution].s[17] = sq_r;
sol[nsolution].s[18] = sq_s;sol[nsolution].s[19] = sq_t;
sol[nsolution].s[20] = sq_u;sol[nsolution].s[21] = sq_v;
sol[nsolution].s[22] = sq_w;sol[nsolution].s[23] = sq_x;
sol[nsolution].s[24] = sq_y;sol[nsolution].s[25] = 0;
nsolution++;
}
void fill(void) {
int i,j,k,l,m,n,o,q, ii,ij,ik,il,im,in,io,iq,wi,wj,wk,wl,wm,wn,wo,wq;
ii = pat1[sq_a].n;
for (i = 0; i < ii; i++) {
wi = pat1[sq_a].r[i];
sq_g = p[wi].d[1];
sq_m = p[wi].d[2];
sq_s = p[wi].d[3];
sq_y = p[wi].d[4];
ij = pat2[ sq_m ].n;
for (j = 0; j < ij; j++) {
wj = pat2[ sq_m ].r[j];
sq_u = p[wj].d[0];
sq_q = p[wj].d[1];
sq_i = p[wj].d[3];
sq_e = p[wj].d[4];
ik = pat3[ sq_a ][ sq_e ].n;
for (k = 0; k < ik; k++) {
wk = pat3[ sq_a ][ sq_e ].r[k];
sq_b = p[wk].d[1];
sq_c = p[wk].d[2];
sq_d = p[wk].d[3];
il = pat4[ sq_b ][ sq_g ][ sq_q ].n;
for (l = 0; l < il; l++) {
wl = pat4[ sq_b ][ sq_g ][ sq_q ].r[l];
sq_l = p[wl].d[2];
sq_v = p[wl].d[4];
im = pat4[ sq_d ][ sq_i ][ sq_s ].n;
for (m = 0; m < im; m++) {
wm = pat4[ sq_d ][ sq_i ][ sq_s ].r[m];
sq_n = p[wm].d[2];
sq_x = p[wm].d[4];
sq_w = dg_sum - sq_u - sq_v - sq_x - sq_y;
if ( sq_w != 1 && sq_w != 3 &&
sq_w != 7 && sq_w != 9 )
continue;
if (prime[sq_u][sq_v][sq_w][sq_x][sq_y] == 0)
continue;
in = pat7[ sq_c ][ sq_m ][ sq_w ].n;
for (n = 0; n < in; n++) {
wn = pat7[ sq_c ][ sq_m ][ sq_w ].r[n];
sq_h = p[wn].d[1];
sq_r = p[wn].d[3];
io = pat8[ sq_g ][ sq_h ][ sq_i ].n;
for (o = 0; o < io; o++) {
wo = pat8[ sq_g ][ sq_h ][ sq_i ].r[o];
sq_f = p[wo].d[0];
sq_j = p[wo].d[4];
iq = pat8[ sq_q ][ sq_r ][ sq_s ].n;
for (q = 0; q < iq; q++) {
wq = pat8[ sq_q ][ sq_r ][ sq_s ].r[q];
sq_p = p[wq].d[0];
sq_t = p[wq].d[4];
sq_k = dg_sum - sq_a-sq_f-sq_p-sq_u;
if ( sq_k < 0 || sq_k > 9 )
continue;
sq_o = dg_sum - sq_e-sq_j-sq_t-sq_y;
if ( sq_o != 1 && sq_o != 3
&& sq_o != 7 && sq_o != 9 )
continue;
if (prime[sq_a][sq_f][sq_k][sq_p][sq_u])
if (prime[sq_k][sq_l][sq_m][sq_n][sq_o])
if (prime[sq_e][sq_j][sq_o][sq_t][sq_y])
solution();
}
}
}
}
}
}
}
}
}
int sol_cmp( const void *va, const void *vb ) {
int i;
SOLUTION *sa = (SOLUTION*)va, *sb = (SOLUTION*)vb;
for (i = 0; i < 25; i++)
{ if (sa->s[i] > sb->s[i]) return 1;
if (sa->s[i] < sb->s[i]) return -1;
}
return 0;
}
int main(void) {
FILE *fin,*fout;
int i,j,k,sum,d0,d1,d2,d3,d4,pp,rt;
fin = stdin;
fout = stdout;
fscanf(fin,"%d %d",&dg_sum,&sq_a);
// generate all 5-digit primes given the digit sum
for ( rt = (int)sqrt(99999), pp = 10008; pp < 99999; pp += 6 )
for (i = pp-1; i <= pp+1; i += 2) {
j = i; sum = 0; k = 0;
while ( j > 0 ) {
p[np].d[4-k++] = j % 10;
sum += p[np].d[5-k];
j /= 10;
}
if (sum != dg_sum)
continue;
for (j = 5; j <= rt; j++)
if ( i % j == 0 )
break;
if ( j == rt+1 ) {
if ( sum == dg_sum )
{
d0 = p[np].d[0]; d1 = p[np].d[1]; d2 = p[np].d[2];
d3 = p[np].d[3]; d4 = p[np].d[4];
// indicate the primes (as digits) for constant lookup
prime[ d0 ][ d1 ][ d2 ][ d3 ][ d4 ] = 1;
// fill-up lookup patterns
pat1[ d0 ].r[pat1[ d0 ].n++ ] = np;
if ( d0 == 1 || d0 == 3 || d0 == 7 || d0 == 9 )
pat2[ d2 ].r[pat2[ d2 ].n++ ] = np;
if ( d1 != 0 && d2 != 0 && d3 != 0 )
pat3[ d0 ][ d4 ].r[pat3[ d0 ][ d4 ].n++] = np;
pat4[ d0 ][ d1 ][ d3 ].r[pat4[ d0 ][ d1 ][ d3 ].n++] = np;
pat7[ d0 ][ d2 ][ d4 ].r[pat7[ d0 ][ d2 ][ d4 ].n++] = np;
pat8[ d1 ][ d2 ][ d3 ].r[pat8[ d1 ][ d2 ][ d3 ].n++] = np;
// store the actual prime value - what a waste
p[np++].val = i;
}
}
}
// recursively fill the entire square (backtrack)
fill();
// printout the solutions
if (nsolution == 0)
fprintf(fout,"NONE\n");
else {
// sort
qsort( &sol, nsolution, sizeof(SOLUTION), sol_cmp);
for (i = 0; i < nsolution; i++) {
for (j = 0; j < 5; j++) {
for ( k = 0; k < 5; k++ )
fprintf(fout,"%d",sol[i].s[j*5+k]);
fprintf(fout,"\n");
}
if (i+1 < nsolution)
fprintf(fout,"\n");
}
}
return 0;
}