- 对称素数:一个整数m的逆序数就是m本身,则称m为对称数,一个整数m如果是对称数又是素数,则称m为对称素数;
例如101,131,929等都是3位对称素数,表现为左右对称;
试统计指定n(1< n <10)位对称素数的个数,并输出其中最大的对称素数;
1.说明:
对于每一个n位奇数m通过以下两道检测:
- 应用试商判别法检测是否为素数,如果不是素数,则返回;
- 分离m的n个数字存储与数组h[j](j=1~n),若j=1~n/2中的某一个出现有 h[j]!=h[n-j+1],m不是对称数,则返回;
凡通过以上两道检测的为n位对称素数,应用s统计个数,并记录其中的最大数;
2.程序设计:
#include<stdio.h>
#include<math.h>
int main()
{
int a,b,c,g,i,j,n,s,h[10];
long m,max,d,t;
printf("请输入位数n(n>1):");
scanf("%d",&n);
s=0;
t=1;
a=n/2;
for(j=1;j<=n-1;j++) /*计算最小的n位整数t*/
t=t*10;
for(m=t+1;m<=(10*t-1);m=m+2) /*枚举最小的n位奇数*/
{
if(m%5==0)
continue;
d=m;
b=0;
for(j=0;j<=9;j++)
h[j]=0;
for(j=1;j<=n;j++)
{
c=d%10;
h[j]=c;
d=d/10;
}
for(j=1;j<=a;j++)
if(h[j]!=h[n-j+1])
{
b=1;
break;
}
if(b==0) /*b=0时m为对称数*/
{
for(g=0,i=2;i<=sqrt(m);i++)
if(m%i==0)
{
g=1;
break;
}
if(g==0) /*g=0时m为对称素数,s统计*/
{
s++;
max=m;
}
}
}
printf("%d位对称素数共有%d个。\n",n,s);
if(s>0)
printf("其中最大的对称素数为:%ld\n",max);
}
3.程序运行示例及其注意事项:
请输入位数n(n>1):7
7位对称素数共有668个。
其中最大的对称素数为:9989899
- 当n为偶数时,是否存在偶数位对称素数?
注意:因偶数位对称数的奇位上的数字之和与偶位上的数字之和相等,该数能被11整除。也就是说,除了11这唯一偶数位对称素数之外,不存在其他偶数位对称素数;
程序改进与拓广
1.说明:
以上程序枚举n位奇数,很多都是无效循环,精简枚举次数是改进设计的关键所在;
注意到对称数首尾对应数字相同的特点,对于奇数n位,只要枚举k=(n+1)/2位整数即可,例如,当n=11时,只要枚举k=6位整数,其他5位根据“对称”赋值即可;
简单枚举k=(n+1)/2位整数也存在问题,其k位整数的首位即最高位不为“0”,可能会产生遗解,因此采用k位整数除个位数字为奇数外,其他各位均取0~9;
程序按n=11设计,即枚举6位,若n<11时,把相应多余循环设置为空循环;
例如,当输入n=9时,设置q[6]=0,因而for(p[6]=0;p[6]< q[6];p[6]++)为空循环,以此类推;
循环中,m为枚举的k=(n+1)/2位整数,e为对称对应的高(n-1)/2位整数,组合为n位整数e即为对称数,设置试商检测素数即可;
2.程序设计:
#include<stdio.h>
#include<math.h>
int main()
{
int g,i,j,k,n,p[7],q[7];
long s;
double e,f,m,max;
printf("请输入奇数n(n<=11):");
scanf("%d",&n);
k=(n+1)/2;
for(i=1;i<=k;i++)
q[i]=9;
for(i=k+1;i<=6;i++)
q[i]=0;
s=0;
max=0;
for(p[6]=0;p[6]<=q[6];p[6]++)
for(p[5]=0;p[5]<=q[5];p[5]++)
for(p[4]=0;p[4]<=q[4];p[4]++)
for(p[3]=0;p[3]<=q[3];p[3]++)
for(p[2]=0;p[2]<=9;p[2]++)
for(p[1]=1;p[1]<=9;p[1]=p[1]+2)
{
if(p[1]==5)
continue;
e=0;
m=0;
f=10;
for(j=1;j<=k-1;j++)
{
e=e*10+p[j];
f=f*10;
m=m*10+p[k+1-j];
}
m=m*10+p[1];
e=e*f+m;
for(g=0,i=3;i<=sqrt(e);i=i+2)
if(fmod(e,i)==0)
{
g=1;
break;
}
if(g==0)
{
s++;
if(max<e)
max=e;
}
}
printf("\n%d位对称素数共有%ld个。\n",n,s);
if(s>0)
printf("其中最大的对称素数为:%0.f\n",max);
}
程序运行示例及其注意事项:
请输入奇数n(n<=11):9
9位对称素数共有5172个。
其中最大的对称素数为:999727999
注意:尽管已经精简了循环,程序的时间复杂度还是指数级的,当n比较大时程序运行的时间还是比较长。例如,n=11时搜索用了近10分钟;
- 变通:在以上程序基础上增加二层循环,同时增加一个输出语句,可以探索到部分n=13或15位对称素数;
例如搜索到9830000000389为13位对称素数,916540000045619为15位对称素数;
注意到n=13或15位对称素数的数量太大,全部搜索时间会更长;

本文探讨了对称素数的概念,即既是左右对称的整数又是素数,如101和131。文章通过程序设计,优化了搜索算法,减少了无效循环,特别指出对于奇数位的对称素数,只需枚举一半位数的整数。虽然已优化,但当n值较大时,程序仍存在指数级时间复杂度,导致运行时间较长。此外,文中提到可以通过增加循环层数来探索更多位数的对称素数。
317

被折叠的 条评论
为什么被折叠?



