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

http://s42.radikal.ru/i096/0907/4e/a4b97b13e14d.jpg

Код:
#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;
}