将1,2,3,4…20这20个自然数排成一个圈,使任意两个相邻的自热数之和均为素数。该如何解决
将1,2,3,4……20这20个自然数排成一个圈,使任意两个相邻的自热数之和均为素数。
[code=C/C++][/code]
希望读者可以耐心看完我的代码。
#include <stdio.h>
#include <math.h>
bool sushu(int m)//判断是否是素数
{
int i;
for(i = 2; i <= sqrt(m) ; i ++)
{
if(m % i == 0)
break;
else
continue;
}
if(i > sqrt(m))
return true;
else
return false;
}
void quan(int a[], int b[], int m, int j)//围圈
{
int i;
for(i = 1; i < m; i ++)
{
if(a[i] != b[j] && sushu(b[j] + a[i]) && a[i] != 0)
{
b[++ j] = a[i];//如果满足条件就将a[i]加到数组b中。
a[i] = 0; //同时将a[i]变成0
quan(a, b, m, j);//继续
}
}
}
int main()
{
int a[20], b[20], i, j;
printf("*******初始化数组**********\n");
for(i = 0; i < 20; i ++)
a[i] = i + 1;
j = 0;
b[j] = a[0];//将b[0]初始化为a[0]
a[0] = 0;
printf("b[%d] = %d\n",j,b[j]);
quan(a, b, 20, j);
printf("\n");
printf("*******围成的圈是**********\n");
for(i = 0; i < 20; i ++)
printf("%d ",b[i]);
printf("\n");
return 0;
}
运行的结果是
想了很久为什么会是这个结果,而且20 + 19 = 39明明是合数,却也将19加进b数组中去了。帮帮忙看一下~~,谢谢了哇~~
------解决方案--------------------
题不是这样做的
要穷举写循环来判断每个是否合法
由于奇偶必须相隔,大概要循环10!*10!次
------解决方案--------------------
还可以简化从1开始,那么下一个只能是(2,4,6,10,12,16,18), 依次计算所有符合条件的数顺序依次循环下去,直到满足条件为止,也许你还可以想出其他办法优化
------解决方案--------------------
如下插入一条打印语句可知为何结果不对:
b[++ j] = a[i];//如果满足条件就将a[i]加到数组b中。
printf("b[%d]=%d\n", j, b[j]);
*******初始化数组**********
b[0] = 1
b[1]=2
b[2]=3
b[3]=4
b[4]=7
b[5]=6
b[6]=5
b[7]=8
b[8]=9
b[9]=10
b[10]=13
b[11]=16
b[12]=15
b[13]=14
b[14]=17
b[15]=12
b[16]=11
b[17]=18
b[18]=19
b[17]=20
*******围成的圈是**********
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 12 11 20 19 -858993460
由上可知,b[17]因递归返回写了2次。j最大达到18,因此b[19]没有赋过值,仍是编译器赋的值0xcccccccc,即-858993460。
LZ应考虑其它算法。
------解决方案--------------------
LZ程序只试了1种排列,而且这个排列不能产生解。应该试多种排列,可按1楼所说完备地查找,也可试其他捷径。以下代码中的排列方法凑巧找到了一个解。
[code=C/C++][/code]
希望读者可以耐心看完我的代码。
#include <stdio.h>
#include <math.h>
bool sushu(int m)//判断是否是素数
{
int i;
for(i = 2; i <= sqrt(m) ; i ++)
{
if(m % i == 0)
break;
else
continue;
}
if(i > sqrt(m))
return true;
else
return false;
}
void quan(int a[], int b[], int m, int j)//围圈
{
int i;
for(i = 1; i < m; i ++)
{
if(a[i] != b[j] && sushu(b[j] + a[i]) && a[i] != 0)
{
b[++ j] = a[i];//如果满足条件就将a[i]加到数组b中。
a[i] = 0; //同时将a[i]变成0
quan(a, b, m, j);//继续
}
}
}
int main()
{
int a[20], b[20], i, j;
printf("*******初始化数组**********\n");
for(i = 0; i < 20; i ++)
a[i] = i + 1;
j = 0;
b[j] = a[0];//将b[0]初始化为a[0]
a[0] = 0;
printf("b[%d] = %d\n",j,b[j]);
quan(a, b, 20, j);
printf("\n");
printf("*******围成的圈是**********\n");
for(i = 0; i < 20; i ++)
printf("%d ",b[i]);
printf("\n");
return 0;
}
运行的结果是
想了很久为什么会是这个结果,而且20 + 19 = 39明明是合数,却也将19加进b数组中去了。帮帮忙看一下~~,谢谢了哇~~
------解决方案--------------------
题不是这样做的
要穷举写循环来判断每个是否合法
由于奇偶必须相隔,大概要循环10!*10!次
------解决方案--------------------
还可以简化从1开始,那么下一个只能是(2,4,6,10,12,16,18), 依次计算所有符合条件的数顺序依次循环下去,直到满足条件为止,也许你还可以想出其他办法优化
------解决方案--------------------
如下插入一条打印语句可知为何结果不对:
b[++ j] = a[i];//如果满足条件就将a[i]加到数组b中。
printf("b[%d]=%d\n", j, b[j]);
*******初始化数组**********
b[0] = 1
b[1]=2
b[2]=3
b[3]=4
b[4]=7
b[5]=6
b[6]=5
b[7]=8
b[8]=9
b[9]=10
b[10]=13
b[11]=16
b[12]=15
b[13]=14
b[14]=17
b[15]=12
b[16]=11
b[17]=18
b[18]=19
b[17]=20
*******围成的圈是**********
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 12 11 20 19 -858993460
由上可知,b[17]因递归返回写了2次。j最大达到18,因此b[19]没有赋过值,仍是编译器赋的值0xcccccccc,即-858993460。
LZ应考虑其它算法。
------解决方案--------------------
LZ程序只试了1种排列,而且这个排列不能产生解。应该试多种排列,可按1楼所说完备地查找,也可试其他捷径。以下代码中的排列方法凑巧找到了一个解。
- C/C++ code
#include <stdio.h> #include <math.h> bool sushu(int m)//判断是否是素数 { int i; for(i = 2; i <= sqrt(m) ; i ++) { if(m % i == 0) break; else continue; } if(i > sqrt(m)) return true; else return false; } int j;//加,把j移出递归以避免重复写b数组 void quan(int a[], int b[], int m/*删, int j*/)//围圈 { int i; for(i = 1; i < m; i ++) { if(a[i] != b[j] && sushu(b[j] + a[i]) && a[i] != 0) { b[++ j] = a[i];//如果满足条件就将a[i]加到数组b中。 a[i] = 0; //同时将a[i]变成0 quan(a, b, m/*删, j*/);//继续 } } } int main() { int a[20], b[20], i/*删, j*/; int k;//加 for (k = 0; k < 20; k++)//加 { //printf("*******初始化数组**********\n"); for(i = 0; i < 20; i ++)// a[i] = 20 - i;//改 a[i] = i + 1; j = 0; b[j] = a[k];//改 b[j] = a[0];//将b[0]初始化为a[0] a[k] = 0;//改 a[0] = 0; //删printf("b[%d] = %d\n",j,b[j]); quan(a, b, 20/*删, j*/); //删printf("\n"); if (j == 19)//加 { printf("围成的圈是: "); for(i = 0; i <= j; i ++)//改 for(i = 0; i < 20; i ++) printf("%d ",b[i]); printf("\n"); } } return 0; }
------解决方案--------------------
#include<stdio.h>
#include<math.h>
#define N 20
bool Prime(int n)