C语言解决回溯法中素数环问题,博客回溯法素数环问题疑惑?

#include

#include

#include

#include

using namespace std;

bool b[11]= {0};

int total=0,a[11]= {0};

int search(int);//回溯过程

int print();//输出方案

bool pd(int,int);//判断素数

int main()

{

search(1);

cout<

}

int search(int t)

{

int i;

for (i=1; i<=10; i++)//有20个数可选

if (pd(a[t-1],i)&&(!b[i]))//判断与前一个数是否构成素数及该数是否可用

{

a[t]=i;

b[i]=1;//跟着i标记

if (t==10)

{

if (pd(a[10],a[1]))

print();

}

else

search(t+1);

b[i]=0;

}

}

int print()

{

total++;

cout<";

for (int j=1; j<=10; j++)

cout<

cout<

}

bool pd(int x,int y)

{

int k=2,i=x+y;

while (k<=sqrt(i)&&i%k!=0)//判断相邻数的和是否是素数

k++;

if (k>sqrt(i))

return 1;

else

return 0;

}

以上是网上博客解决素数环的问题,我一直比较疑惑的点是最终的输出结果为什么只有1,2,3,5,7开头的,4,6,8,9,10开头的呢

当前结果6 1 10 7 4 9 2 3 8 5

当前结果6 1 10 7 4 9 8 3 2 5

当前结果6 1 10 9 2 5 8 3 4 7

当前结果6 1 10 9 8 5 2 3 4 7

比如以上也是满足的

另外一个穷举法

#include

#include

using namespace std;

int A[100], isp[100], n;//isp是素数表,用于存放素数

int is_prime(int x){

for(int i = 2; i 

if(x % i == 0) return 0;

}

return 1;

}

void printPrime(){

//生成第一个排列,顺序排列, A[1] = 1 A[2] = 2

for(int i = 1; i <= n; i++){

A[i] = i;

}

do{

bool ok = true;

for(int i = 1; i 

int index = A[i]+A[i+1];

if(!isp[index]){

ok = false;

break;

}

}

//第一个和最后一个数的和

if(!isp[A[1] + A[n]]){

ok = false;

}

if(ok){

cout <

for(int i = 1; i <= n; i++){

cout <

}

cout <

}

} while(next_permutation(A+2, A+n+1));//第一个一定为1不变,只更新第2个到最后1个的排列

}   //因为A[0]=0,A[1]=1

int main(){

cin >> n;

//记录1~n*2的值是否为素数

for(int i = 2; i <= n*2; i++){

isp[i] = is_prime(i);

}

printPrime();

} 穷举法却可以有1到10开头的都有,我想不明白第一个程序为什么不能输出全部,实在想不明白,希望大佬指点一下,

以下是使用C语言编写回溯法素数问题的示例代码: ```c #include <stdio.h> #include <stdbool.h> #include <math.h> #define MAX_N 20 // 最大长 // 判断一个数是否为素数 bool is_prime(int n) { if (n < 2) { return false; } for (int i = 2; i <= sqrt(n); i++) { if (n % i == 0) { return false; } } return true; } // 查找 1 到 n 之间的素数 void find_primes(int n, int primes[]) { int count = 0; for (int i = 2; i <= n; i++) { if (is_prime(i)) { primes[count++] = i; } } } // 回溯搜索素数 void search(int n, int ring[], bool used[], int primes[], int index) { if (index == n) { // 找到一个解 if (is_prime(ring[0] + ring[n - 1])) { // 检查首尾是否相邻 for (int i = 0; i < n; i++) { printf("%d ", ring[i]); // 输出 } printf("\n"); } } else { for (int i = 1; i < n; i++) { if (!used[i] && is_prime(primes[i] + ring[index - 1])) { ring[index] = primes[i]; // 将素数加入 used[i] = true; // 标记已使用 search(n, ring, used, primes, index + 1); // 继续搜索 used[i] = false; // 回溯,标记为未使用 } } } } // 寻找 n 阶素数 void prime_ring(int n) { int primes[MAX_N]; // 存储素数 find_primes(n, primes); // 查找 1 到 n 之间的素数 int ring[MAX_N]; // 存储 bool used[MAX_N] = {false}; // 标记已使用的素数 ring[0] = 1; // 确定第一个位置为1 used[0] = true; // 第一个位置已使用 search(n, ring, used, primes, 1); // 从第二个位置开始搜索 } // 主函数 int main() { int n = 8; // 的阶数 prime_ring(n); // 寻找 n 阶素数 return 0; } ``` 注释说明: - 第5-13行:定义判断素数的函数 `is_prime`,使用循从 $2$ 到 $\sqrt{n}$ 遍历所有数,判断 $n$ 是否为素数。 - 第15-22行:定义查找素数列表的函数 `find_primes`,使用循遍历 $2$ 到 $n$ 之间的所有数,调用 `is_prime` 函数判断是否为素数,并将素数存储在数组返回。 - 第24-37行:定义回溯搜索函数 `search`,如果找到一个解则输出,否则对于每个位置,遍历素数列表,找到一个没有被使用的素数,使得它和前一个位置的素数之和为素数。如果找到了这样的素数,将它加入,标记为已使用,然后递归搜索下一个位置。如果在某个位置上找不到合适的素数,则回溯到上一个位置,并且把该位置的素数标记为未使用。 - 第39-48行:定义寻找素数的函数 `prime_ring`,查找 1 到 n 之间的素数,初始化和已使用数组,从第二个位置开始搜索。 - 第50-54行:在主函数定义的阶数,调用 `prime_ring` 函数寻找素数。 请注意,这只是一个简单的示例代码,实际上回溯法的应用非常广泛,具体实现方式会因应用场景而有所不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值