The Primes

题意:有一个5*5的方阵,每行(从左至右)、每列(从上至下)和两条对角线(从左到右)上的5位数都是质数,且质数每位的数字之和一样。给定这个数字之和N以及方阵左上角的数M,求出所有的5*5方阵

解题思路

  1. 求出所有符合条件的5位质数
  2. 按照上图,首先根据给定的左上角的数M来确定一条对角线上的数,满足条件的五位数在1中求出的集合中找,在图中以0来表示
  3. 在2的基础上用多重循环分别列举各位上的数,列举的顺序在上图中给出,其中带括号的意味着可以根据所在的行(列、对角线)的数字之和N推出
  4. 如果数字之和已经超过N,及时break掉该层循环,达到剪枝的目的
  5. 第一行(列)上的数不能为0,最后一行(列)上的数只能为1,3,7,9,这也是很重要的剪枝
  6. 确定一行(列、对角线)上所有的数之后,要看该数是否是质数。如果不是则continue该层循环,如果是则进入下层循环
  7. 在确定所有的数之后,还需要检测中间一列是否满足条件,如果满足则此5*5方阵是答案中的一个,存储下来
  8. 最后将存储下来的答案排序输出即可

代码

/*
ID: zc.rene1
LANG: C
PROG: prime3
 */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

int N, M;
int digits[5];
int primes[90000][5];
int prime_num = 0;
int matrix[5][5];
int map[10][10][10][10][10];

int result[100][25];
int result_num = 0;

int IsPrime(void)
{
   int sum = 0;
   int i;

   for (i=0; i<5; i++)
   {
       sum *= 10;
       sum += digits[i];
   }
   
   for (i=2; i<=sqrt(sum); i++)
   {
       if (sum % i == 0)
       {
	   return 0;
       }
   }
   return 1;
}

void Check(void)
{
    int i;
    int sum = 0;

    for (i=0; i<5; i++)
    {
	sum += digits[i];
    }

    if (sum == N)
    {
	if (IsPrime())
	{
	    memcpy(primes[prime_num], digits, 5 * sizeof(int));
	    map[digits[0]][digits[1]][digits[2]][digits[3]][digits[4]] = prime_num;
	    prime_num++;
	}
    }
}

int DFS(int depth)
{
    int i;
    
    if (depth == 5)
    {
	Check();
	return ;
    }

    for (i=0; i<=9; i++)
    {
	digits[depth] = i;
	DFS(depth + 1);
    }
}

void Search(void)
{
    int i = 0, j;
    int x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20;

    while (primes[i][0] != M)
    {
	i++;
    }

    while (primes[i][0] == M)
    {
	/*diagonal*/
	for (j=0; j<5; j++)
	{
	    matrix[j][j] = primes[i][j];
	}
	/*1 2 3 (4)*/
	for (x1=1; x1<=9; x1+=2)
	{
	    if (x1 == 5)
	    {
		continue;
	    }
	    if (x1 + matrix[2][2] > N)
	    {
		break;
	    }
	    for (x2=1; x2<=9; x2+=2)
	    {
		if (x2 == 5)
		{
		    continue;
		}
		if (x1 + x2 + matrix[2][2] > N)
		{
		    break;
		}
		for (x3=0; x3<=9; x3++)
		{
		    x4 = N - (x1 + x2 + x3 + matrix[2][2]);
		    if (x4 < 0)
		    {
			break;
		    }
		    if (map[x1][x3][matrix[2][2]][x4][x2] != -1)
		    {
			matrix[4][0] = x1;
			matrix[3][1] = x3;
			matrix[1][3] = x4;
			matrix[0][4] = x2;
			/*5 6 (7)*/
			for (x5=1; x5<=9; x5+=2)
			{
			    if (x5 == 5)
			    {
				continue;
			    }
			    if (x2 + x5 + matrix[4][4] > N)
			    {
				break;
			    }
			    for (x6=1; x6<=9; x6+=2)
			    {
				if (x6 == 5)
				{
				    continue;
				}
				x7 = N - (x2 + x5 + x6 + matrix[4][4]);
				if (x7 < 0)
				{
				    break;
				}
				if (map[x2][x5][x7][x6][matrix[4][4]] != -1)
				{
				    matrix[1][4] = x5;
				    matrix[3][4] = x6;
				    matrix[2][4] = x7;
				    /*8 9 (10)*/
				    for (x8=1; x8<=9; x8+=2)
				    {
					if (x8 == 5)
					{
					    continue;
					}
					if (x1 + x8 + matrix[4][4] > N)
					{
					    break;
					}
					for (x9=1; x9<=9; x9+=2)
					{
					    if (x9 == 5)
					    {
						continue;
					    }
					    x10 = N - (x1 + x8 + x9 + matrix[4][4]);
					    if (x10 < 0)
					    {
						break;
					    }
					    if (map[x1][x8][x10][x9][matrix[4][4]] != -1)
					    {
						matrix[4][1] = x8;
						matrix[4][3] = x9;
						matrix[4][2] = x10;
						/*11 (12)*/
						for (x11=1; x11<=9; x11++)
						{
						    x12 = N - (x11 + matrix[1][1] + x3 + x8);
						    if (x12 < 0)
						    {
							break;
						    }
						    if (map[x11][matrix[1][1]][x12][x3][x8] != -1)
						    {
							matrix[0][1] = x11;
							matrix[2][1] = x12;
							/*13 (14)*/
							for (x13=1; x13<=9; x13++)
							{
							    x14 = N - (x13 + matrix[1][1] + x4 + x5);
							    if (x14 < 0)
							    {
								break;
							    }
							    if (map[x13][matrix[1][1]][x14][x4][x5] != -1)
							    {
								matrix[1][0] = x13;
								matrix[1][2] = x14;
								/*15 (16) (17) (18) (19) (20)*/
								for (x15=1; x15<=9; x15++)
								{
								    x16 = N - (x15 + x4 + matrix[3][3] + x9);
								    if (x16 < 0)
								    {
									break;
								    }
								    if (map[x15][x4][x16][matrix[3][3]][x9] != -1)
								    {
									x17 = N - (matrix[0][0] + x11 + x15 + x2);
									if (x17 < 0)
									{
									    continue;
									}
									if (map[matrix[0][0]][x11][x17][x15][x2] != -1)
									{
									    x18 = N - (x12 + matrix[2][2] + x16 + x7);
									    if (x18 < 0)
									    {
										continue;
									    }
									    if (map[x18][x12][matrix[2][2]][x16][x7] != -1)
									    {
										x19 = N - (matrix[0][0] + x13 + x18 + x1);
										if (x19 < 0)
										{
										    continue;
										}
										if (map[matrix[0][0]][x13][x18][x19][x1] != -1)
										{
										    x20 = N - (x19 + x3 + matrix[3][3] + x6);
										    if (x20 < 0)
										    {
											continue;
										    }
										    if (map[x19][x3][x20][matrix[3][3]][x6] != -1)
										    {
											matrix[0][3] = x15;
											matrix[2][3] = x16;
											matrix[0][2] = x17;
											matrix[2][0] = x18;
											matrix[3][0] = x19;
											matrix[3][2] = x20;
											/*test if satisfied*/
											if (map[x17][x14][matrix[2][2]][x20][x10] != -1)
											{
											    memcpy(result[result_num], matrix, 25 * sizeof(int));
											    result_num++;
											}
										    }
										}
									    }
									}
								    }
								}
							    }
							}
						    }
						}
					    }
					}
				    }
				}
			    }
			}
		    }
		}
	    }
	}
	i++;
    }
}

int IsBigger(int a[25], int b[25])
{
    int i;

    for (i=0; i<25; i++)
    {
	if (a[i] < b[i])
	{
	    return 0;
	}
	else if (a[i] > b[i])
	{
	    return 1;
	}
    }
    return 0;
}

void Sort(void)
{
    int i, j;
    int temp[25];

    for (j=result_num-1; j>0; j--)
    {
	for (i=0; i<j; i++)
	{
	    if (IsBigger(result[i], result[i + 1]))
	    {
		memcpy(temp, result[i], 25 * sizeof(int));
		memcpy(result[i], result[i+1], 25 * sizeof(int));
		memcpy(result[i+1], temp, 25 * sizeof(int));
	    }
	}
    }
}

int main(void)
{
    FILE *fin, *fout;
    int i, j;

    fin = fopen("prime3.in", "r");
    fout = fopen("prime3.out", "w");

    fscanf(fin, "%d %d", &N, &M);
    memset(map, -1, 100000 * sizeof(int));

    for (i=1; i<=9; i++)
    {
	digits[0] = i;
	DFS(1);
    }

    memset(matrix, -1, 25 * sizeof(int));
    Search();

    Sort();

    for (i=0; i<result_num; i++)
    {
	for (j=0; j<25; j++)
	{
	    fprintf(fout, "%d", result[i][j]);
	    if (j % 5 == 4)
	    {
		fprintf(fout, "\n");
	    }
	}
	if (i != result_num -1)
	{
	    fprintf(fout, "\n");
	}
    }
    if (result_num == 0)
    {
	fprintf(fout, "NONE\n");
    }

    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值