将1,2,3,4……20这20个自然数排成一个圈,使任意两个相邻的自热数之和均为素数。

tingting5278910 2012-03-23 02:16:25


希望读者可以耐心看完我的代码。
#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数组中去了。帮帮忙看一下~~,谢谢了哇~~
...全文
670 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
JackBurd 2012-03-25
  • 打赏
  • 举报
回复
谢谢楼主厚爱啊,哈哈。
tingting5278910 2012-03-24
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 logiciel 的回复:]
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……
[/Quote]

谢谢你,不过这个解不对哦,因为20 + 1是个合数。
logiciel 2012-03-24
  • 打赏
  • 举报
回复
LZ程序只试了1种排列,而且这个排列不能产生解。应该试多种排列,可按1楼所说完备地查找,也可试其他捷径。以下代码中的排列方法凑巧找到了一个解。
#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;
}


围成的圈是: 20 17 14 15 16 13 18 19 12 11 8 9 10 7 6 5 2 3 4 1
yanziguilai 2012-03-24
  • 打赏
  • 举报
回复
#include<iostream>
using namespace std;
bool prime[40];
int a[21];
void dfs(int k,int n)
{
int i,j;
if(k==n&&prime[a[0]+a[n-1]]==0)
{
printf("1");
for(i=1;i<n;i++) printf(" %d",a[i]);
printf("\n");
return ;
}
else
for(i=2;i<=n;i++)
{
int ok=0;
a[k]=i;
for(j=0;j<k;j++)
if(a[j]==i||prime[i+a[k-1]]==1){ ok=1;break;}
if(ok==0) dfs(k+1,n);
}
}

int main()
{
int n,cnt=1,i,j;
for(i=3;i<40;i++)
for(j=2;j*j<=i;j++)
if(i%j==0) { prime[i]=1;break;}

while(scanf("%d",&n)!=EOF)
{

printf("Case %d:\n",cnt++);
a[0]=1;
dfs(1,n);
printf("\n");
}
return 0;
}
看了一下lz的
自己写了一个 通过测试了http://acm.hdu.edu.cn/diy/contest_search.php?action=go
JackBurd 2012-03-24
  • 打赏
  • 举报
回复
#include<stdio.h>
#include<math.h>

#define N 20

bool Prime(int n)
{
int k = (int)sqrt(n);

for(int i = 2; i <= k; i ++)
{
if(n % i == 0)
{
return false;
}
}

return true;
}

bool Check(int a[], int n, int i)
{
for(int j = 0; j < n; j ++)
{
if(a[j] == i)
{
return false;
}
}

if(n < N-1)
{
return (Prime(a[n-1]+i));
}
else
{
return (Prime(a[0]+i) && Prime(a[n-1]+i));
}
}

void PrimeCircle(int a[], int n)
{
for(int i = 1; i <= N; i ++)
{
if(Check(a,n,i))
{
a[n] = i;

if(n == N-1)
{
for(int j = 0; j < N; j ++)
{
printf("%d ", a[j]);
}
printf("\n");
}
else
{
PrimeCircle(a, n+1);
}

a[n] = 0;
}
}
}

void main()
{
int a[N];

PrimeCircle(a, 0);
}
这个可以求出所有解,你看哈。
logiciel 2012-03-23
  • 打赏
  • 举报
回复
如下插入一条打印语句可知为何结果不对:
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应考虑其它算法。

nice_cxf 2012-03-23
  • 打赏
  • 举报
回复
还可以简化从1开始,那么下一个只能是(2,4,6,10,12,16,18), 依次计算所有符合条件的数顺序依次循环下去,直到满足条件为止,也许你还可以想出其他办法优化
tingting5278910 2012-03-23
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 nice_cxf 的回复:]
题不是这样做的
要穷举写循环来判断每个是否合法
由于奇偶必须相隔,大概要循环10!*10!次
[/Quote]
循环那么多次会运行很慢的。
tingting5278910 2012-03-23
  • 打赏
  • 举报
回复
嗯?插入的图片看不了。

还是手写吧。

结果是:1 2 3 4 7 6 5 8 9 10 13 16 15 17 12 11 20 19 -858993460
nice_cxf 2012-03-23
  • 打赏
  • 举报
回复
题不是这样做的
要穷举写循环来判断每个是否合法
由于奇偶必须相隔,大概要循环10!*10!次

70,019

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧