连续合数探求
来源:互联网 发布:泳衣淘宝网 编辑:程序博客网 时间:2024/06/06 07:00
本节探讨连续合数问题,实际上还是与素数密切相关;
最多连续合数区间中不能存在素数,最小连续n个合数中也不能存在素数;
最多连续合数区间
试在指定区间 [c,d] 内探求最多连续合数的个数及最多连续合数的起始与终止数;
例如输入c,d:10,100,在区间[10,100]内最多连续合数的个数为7个,所求得的连续合数区间为:[90,96];
下面应用试商法与筛法两种设计分别求解;
应用试商设计:
1.说明:
对指定区间[c,d]内的每一个奇数i应用试商法判别是否为素数,若i(t=0)为素数,则i-f(f为i前面的素数)与max比较以求取最多并用变量f1和i1记录;
随后,f=i即把素数i赋值给f,为下一个素数进行比较做准备;
最多连续合数的起始数f+1有可能与区间起始数c重合,因而当c为偶数或非素数时有必要作赋值:f=c-1;
注意:以上比较所得max不是f与i之间的合数个数,max比f与i之间的合数个数多了1;
2.程序设计:
#include<stdio.h>#include<math.h>int main(){ long c,d,i,j,f,t,f1,i1,max; printf("请输入c,d(2<c<d):"); scanf("%ld,%ld",&c,&d); f=c; max=0; if(c%2!=0) { for(t=0,j=3;j<=sqrt(c);j+=2) /*试商判别下限c是否为素数*/ if(c%j==0) { t=1; break; } } if(c%2==0||t==1) /*令c-1为素数并赋值给f*/ f=c-1; if(c%2==0) c++; for(i=c;i<=d;i+=2) { t=0; for(j=3;j<=sqrt(i);j+=2) /*试商判别素数*/ if(i%j==0) { t=1; break; } if(d-i<2 && t==1) { t=0; i=d+1; /*令d+1为素数并赋值给i*/ } if(t==0) /*t为0表明i为素数*/ { if(i-f>max) { max=i-f; f1=f+1; i1=i-1; } f=i; /*f为i的前一个素数*/ } } printf("最多连续合数的个数为:%ld\n",max-1); printf("连续合数区间为:[%ld,%ld]\n",f1,i1);}
3.程序运行示例:
请输入c,d(2<c<d):10000,1000000最多连续合数的个数为:113连续合数区间为:[492114,492226]
应用筛法:
求出区间 [c,d] 内的所有相邻素数对f,m,求取m-f的最大值max;
注意到本题的搜索范围较大,采用效率较高的筛法求素数是适宜的;
1.说明:
应用筛法求素数,为了方便实施“划去”操作,设置数组;
考虑到有时待测区间[c,d]比较大,为不使数组下标超维,把[c,d]分割为若干个子区间[cs,ds],确保在子区间中操作不超维;
每一数组元素对应一个待判断的奇数,并赋初值0,如果该奇数为p的倍数则应划去,对应元素加一个划去标记,通常给该元素赋值-1,最后,打印元素值不是-1(即没有划去)的元素对应的奇数即所求素数;
在实际应用筛法的过程中,p通常不限于取不超过sqrt(x)的素数,而是适当放宽取不超过sqrt(x)的奇数(从3开始),这样做尽管多了一些重复划去操作,但程序实现要简便些;
在指定区间[cs,ds](约定cs为奇数)上所有奇数表示为j=cs+2k(k=0,1,……,e,这里e=(ds-cs)/2),于是k=(j-cs)/2是奇数j在数组中的序号(下标),如果j为奇数的倍数时,对应数组元素作划去标记,即a[(j-cs)/2]=-1;
根据cs与奇数i确定g=2*int(cs/(2 * i))+1,使得gi接近区间下限cs,从而使划去的gi,(g+2) * i,……在[cs,ds]中,减少无效操作,以提高对大区间的筛选效率;
最后,凡数组元素a[k]!=-1,对应的奇数j=cs+2k就为素数;
2.程序设计:
#include<stdio.h>#include<math.h>int main(){ long c,d,cs,ds,ct,dt,f,g,i,j,k,m,max,a[11000]; int e,u,x,y; printf("请输入c,d(2<c<d):"); scanf("%ld,%ld",&c,&d); if(d-c<=20000) { cs=c; ds=d; x=0; } else { x=(d-c)/20000; cs=c; ds=d-20000*x; } f=cs; max=0; for(y=1;y<=x+1;y++) /*把[c,d]分x+1个子区间筛选素数*/ { if(cs%2==0) cs++; for(i=0;i<=10999;i++) a[i]=0; e=(ds-cs)/2; i=1; while(i<=sqrt(ds)) { i=i+2; g=2*(cs/(2*i))+1; if(g*i>ds) continue; if(g==1) g=3; j=i*g; while(j<=ds) { if(j>=cs) /*赋值筛去标记-1*/ a[(j-cs)/2]=-1; j=j+2*i; } } for(u=1,k=0;k<=e;k++) { if(a[k]!=-1) { m=cs+2*k; /*m即筛选所得素数*/ if(m-f>max) /*寻求两相邻素数间距的最大值*/ { max=m-f; ct=f+1; dt=cs+2*k-1; } f=m; } } cs=ds+1; ds=ds+20000; /*cs与ds增长后继续探求*/ } printf("最多连续合数的个数为:%ld\n",max-1); printf("连续合数区间为:[%ld,%ld]\n",ct,dt);}
3.程序运行示例及其注意事项:
请输入c,d(2<c<d):10,10000000最多连续合数的个数为:153连续合数区间为:[4652354,4652506]
注意:如果测试的区间比较大,应用筛法所需时间比试商判别要短,有兴趣的读者不妨用实例进行比较;
最小连续n个合数
试求出最小的连续n个合数(其中n是键盘输入的任意正整数);
例如输入n=7,最小的连续7个合数为 [90,96];
1.说明:
求出区间 [c,d] 内的所有素数(区间起始数c可由小到大递增),检验其中每相邻两素数之差,若某相邻的两素数m和f之差大于n,即m-f>n,则区间[f+1,f+n]中的n个数为最小的连续n个合数;
应用试商法求指定区间[c,d](约定起始数 c=3,d=c+10000)上的所有素数,求出该区间内的一个素数m,设前一个素数为f,判别:若m-f>n,则输出结果[f+1,f+n]后结束;否则,作赋值f=m,为求下一个素数做准备;
如果在区间[c,d]中没有满足条件的解,则作赋值:c=d+2,d=c+10000,继续试商下去,直到找出所要求的解;
2.程序设计:
#include<stdio.h>#include<math.h>int main(){ long c,d,f,m,j; int t,n; printf("求最小的n个连续合数。\n"); printf("请输入n(n<200):"); scanf("%d",&n); c=3; d=c+10000; f=3; while(1) { for(m=c;m<=d;m+=2) { for(t=0,j=3;j<=sqrt(m);j+=2) if(m%j==0) /*实施试商*/ { t=1; break; } if(t==0 && m-f>n) /*满足条件进行输出*/ { printf("最小的%d个连续合数区间为:",n); printf("[%ld,%ld] \n",f+1,f+n); return; } if(t==0) /*每求出一个素数m后赋值给f*/ f=m; } if(m>d) { c=d+2; /*每一轮试商后改变c和d转下一轮*/ d=c+10000; } }}
3.程序运行示例及其注意事项:
求最小的n个连续合数。请输入n(n<200):100最小的100个连续合数区间为:[370262,370361]。
注意:随着n的增加,最小的n个连续合数也随之迅速变大,搜索也随之变得困难,例如输入n=200,搜索最小的200个连续合数区间[20831324,20831523]所有的时间就比较长;
- 连续合数探求
- 不会出现连续偶数个合数????
- 不会出现连续偶数个合数????
- 求连续十个最小的合数
- 请找出十个最小的连续自然数,它们个个都是合数(非素数)
- 连续x次奇数(n+2*x)是合数的算法题暴力算法
- 找出十个最小的连续自然数,它们个个都是合数(非素数)。
- 十个最小的连续自然数,并且这十个数都为合数(非素数)
- 素数探求
- 合数乘积
- 计算合数
- uva11752(合数)
- 合数相关
- 合数分解
- 合数世纪
- 探求JavaScript开发工具
- 探求JavaScript开发工具
- 探求真正的SOA
- mysql 5.7 版本后数据没有字段 password 所以修改 root 密码 需要
- PostgreSQL表空间创建、删除
- Leetcode 85. Maximal Rectangle (Hard) (cpp)
- C#多线程同步(二)【Mutex】
- 公共子序列(lcs)
- 连续合数探求
- shell使用命令计算md5
- Android studio 图片加载框架Glide介绍及使用
- 修改centos 7.0 的yum源优先级priority
- ArcGIS Engine控件运行许可学习总结
- The `master` repo requires CocoaPods 1.0.0 - (currently using 0.39.0)
- Java ThreadPoolExecutor机制
- 欢迎使用CSDN-markdown编辑器
- C#视频之面向对象