在3x3的方格中填入数字1~N(N>0)中的某9个数字,每个方格填1个整数,使相邻的两个方格中的整数之和为质数。求满足以上要求的各种数字填法。
【分析】
利用试探法找到问题的解,即从第一一个方格开始, 为当前方格寻找一个合理的整数填入,并在当前位置正确填入后,为下一方格寻找可填入的合理整数。如果不能为当前方格找到一个合理的可填整数,就要回退到前一方格,调整前一方格的填入数。当第9个方格也填入合理的整数后,就找到了一个解,将该解输出,并调整第9个填入的整数,继续寻找下一个解。为了检查当前方格填入整数的合理性,引入二维数组checkMatrix 存放需要合理性检查的相邻方格的序号。
为了找到一个满足要求的9个数的填法,按照某种顺序(如从小到大)每次在当前位置填入一个整数,然后检查当前填入的整数是否能够满足要求。在满足要求的情况下,继续用同样的方法为下一方格填入整数。 如果最近填入的整数不能满足要求,就改变填入的整数。 如果对当前方格试尽所有可能的整数,都不能满足要求,就得回退到前一方格 (回溯),并调整该方格填入的整数。如此重复扩展、检查、调整,直到找到一个满足问题要求的解, 将解输出。
code:
#include<stdio.h>
#define N 12
int b[N + 1];
int a[10];/*存放方格填入的整数*/
int total = 0;/*共有多少种填法*/
int checkmatrix[][3] = { { -1 },{ 0,-1 },{ 1,-1 },
{ 0,-1 },{ 1,3,-1 },{ 2,4,-1 },
{ 3,-1 },{ 4,6,-1 },{ 5,7,-1 } };
void write(int a[])
/*输出方格中的数字*/
{
int i, j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
printf("%3d", a[3 * i + j]);
printf("\n");
}
}
int isprime(int m)
/*判断m是否是质数*/
{
int i;
int primes[] = { 2,3,5,7,11,17,19,23,29,-1 };
if (m == 1 || m % 2 == 0)
return 0;
for (i = 0; primes[i]>0; i++)
if (m == primes[i])
return 1;
for (i = 3; i*i <= m;)
{
if (m%i == 0)
return 0;
i += 2;
}
return 1;
}
int selectnum(int start)
/*从start开始选择没有使用过的数字*/
{
int j;
for (j = start; j <= N; j++)
if (b[j])
return j;
return 0;
}
int check(int pos)
/*检查填入的pos位置是否合理*/
{
int i, j;
if (pos < 0)
return 0;
/*判断相邻的两个数是否是质数*/
for (i = 0; (j = checkmatrix[pos][i]) >= 0; i++)
if (!isprime(a[pos] + a[j]))
return 0;
return 1;
}
int extend(int pos)
/*为下一个方格找一个还没有使用过的数字*/
{
a[++pos] = selectnum(1);
b[a[pos]] = 0;
return pos;
}
int change(int pos)
/*调整填入的数,为当前方格寻找下一个还没有用到的数*/
{
int j;
/*如果所有数都被使用,则回溯*/
while (pos >= 0 && (j = selectnum(a[pos] + 1)) == 0)
b[a[pos--]] = 1;
if (pos < 0)
return -1;
b[a[pos]] = 1;
a[pos] = j;
b[j] = 0;
return pos;
}
void find()
/*查找*/
{
int ok = 0, pos = 0;
a[pos] = 1;
b[a[pos]] = 0;
do
{
if (ok)
if (pos == 8)
{
total++;
printf("第%d种填法\n", total);
write(a);
pos = change(pos);/*调整*/
}
else
pos = extend(pos);/*扩展*/
else
pos = change(pos);/*调整*/
ok = check(pos);/*检查*/
} while (pos >= 0);
}
void main()
{
int i;
for (i = 1; i <= N; i++)
b[i] = 1;
find();
printf("共有%d种填法\n", total);
getchar();
}
结果:
来源:CSDN
作者:凌空的桨
链接:https://blog.csdn.net/baidu_36669549/article/details/104156835