提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
一、什么是回文数和回文素数
回文数就是一个阿拉伯数字,无论从左往右还是从右往左看都是一样的,类似于轴对称吧
那么在这些回文数的基础上分离出来具有素数特性的就是回文素数啦。
二、关于回文数的生成原理以及回文素数的处理
我数学不好:
关于回文数的结构我是这么拆分理解的
在此基础上 只要再设计一个较好的素数判断函数对生成的回文数进行判断,即可对具有素数特性的回文数筛选出来
这里介绍两个:
//两种类型的返回值都是 0 或则 n(回文素数)
//素数判法一
int fun(int n)
{
int j;
for(j=2;j<sqrt(n);j++)
{
if(n%j==0)
return 0;
}
return n;
}
//素数判断法二
int test(int num)
{
double a = num;
if (num == 2 || num == 3)
return num;
if (num % 6 != 1 && num % 6 != 5)
return 0;
double tmp = sqrt(a);
int i = 0;
for (i = 5; i <= tmp; i += 6)
if (num % i == 0 || num % (i + 2) == 0)
return 0;
return num;
}
三、例题
1.各位数 回文数 个数的统计
生成一个回文数的思路已知,设计一个会生成回文数的函数,让其进入后已知生成其位数上全部回文数,我对其计数即可
其实在上述的基础上口算都知道
3位数(90)。。。 5位数(900)。。。7位数(9000)。。。。 9位数(90000)
代码奉上:
虽然代码数量大,但思路简单明了 ,重复设计了多个相同原理的回文数生成函数
相应负责各自位数的回文数生成工作
#include<stdio.h>
#include<math.h>
int test9(void)
{
int i1, i2, i3, num,sum = 0, zd,s;
for (s = 1; s < 10; s++)
{
for (i3 = 0; i3 < 10; i3++)
{
for (i2 = 0; i2 < 10; i2++)
{
for (i1 = 0; i1 < 10; i1++)
{
for (zd = 0; zd < 10; zd++)
{
num = s * pow(10.0, 8.0) + i3 * pow(10.0, 7.0) + i2 * pow(10.0, 6.0) + i1 * pow(10.0, 5.0) + zd * pow(10.0, 4.0) + i1 * pow(10.0, 3.0) + i2 * pow(10.0, 2.0) + i3 * pow(10.0, 1.0) + s;
sum++;
}
}
}
}
}
return sum;
}
int test7(void)
{
int i1, i2, num, sum = 0, zd, s;
for (s = 1; s < 10; s++)
{
for (i2 = 0; i2 < 10; i2++)
{
for (i1 = 0; i1 < 10; i1++)
{
for (zd = 0; zd < 10; zd++)
{
num = s * pow(10.0, 6.0) + i2 * pow(10.0, 5.0) + i1 * pow(10.0, 4.0) + zd* pow(10.0, 3.0) + i1 * pow(10.0, 2.0) + i2 * pow(10.0, 1.0) + s;
sum++;
}
}
}
}
return sum;
}
int test5(void)
{
int i1, num, sum = 0, zd = 0,s;
for (s = 1; s < 10; s++)
{
for (i1 = 0; i1 < 10; i1++)
{
for (zd = 0; zd < 10; zd++)
{
num = s * pow(10.0, 4.0) + i1 * pow(10.0, 3.0) + zd * pow(10.0, 2.0) + i1 * pow(10.0, 1.0) + s;
sum++;
}
}
}
return sum;
}
int test3(void)
{
int num, sum = 0, zd = 0,s;
for (s = 1; s < 10; s++)
{
for (zd = 0; zd < 10; zd++)
{
num = s * pow(10.0, 3.0) + zd * 10 + s;
sum++;
}
}
return sum;
}
int main()
{
int i = 0, sum = 0;
int w = 0, s = 0;
scanf("%d", &w);//输入位数
// 设计问题 没用 switch语句 这里通过位数的区别 选择回文数生成函数
if (w == 1)
{
sum = 10;
}
if (w == 2)
{
sum = 9;
}
if (w == 3)
{
sum = test3();
}
if (w == 5)
{
sum = test5();
}
if (w == 7)
{
sum = test7();
}
if (w == 9)
{
sum = test9();
}
printf("%d", sum);
return 0;
}
2.各位数 回文素数 的输出以及个数统计
那么在上一道题的基础上,只需要插入素数判断函数,对回文素数进行筛选出来,再用数组存储,事成之后直接打印,方便的一批。
先知道:
很明显创建个 6000 个元素的数组完全够哈
代码奉上:
#include<stdio.h>
#include<math.h>
#include <time.h>
#include <windows.h>
int arr[10000] = { 0 };
//int test(int num)//判断素数法1
//{
// double a = num;
// if (num == 2 || num == 3)
// return num;
//
// if (num % 6 != 1 && num % 6 != 5)
// return 0;
//
// double tmp = sqrt(a);
// int i = 0;
//
//
// for (i = 5; i <= tmp; i += 6)
// if (num % i == 0 || num % (i + 2) == 0)
// return 0;
//
//
// return num;
//}
int test(int n)//判断素数法2
{
int j;
for (j = 2; j <= sqrt(n); j++)
{
if (n % j == 0)
return 0;
}
return n;
}
void test9(void)
{
int i1, i2, i3, num, ret, i = 0, zd = 0,s=0;
for (s = 1; s < 10; s++)
{
for (i3 = 0; i3 < 10; i3++)
{
for (i2 = 0; i2 < 10; i2++)
{
for (i1 = 0; i1 < 10; i1++)
{
for (zd = 0; zd < 10; zd++)
{
num = s * pow(10.0, 8.0) + i3 * pow(10.0, 7.0) + i2 * pow(10.0, 6.0) + i1 * pow(10.0, 5.0) + zd * pow(10.0, 4.0) + i1 * pow(10.0, 3.0) + i2 * pow(10.0, 2.0) + i3 * pow(10.0, 1.0) + s;
if (num % 2 == 0)
continue;
else
{
ret = test(num);
if (ret != 0)
{
arr[i] = ret;
i++;
}
}
}
}
}
}
}
}
void test7(void)
{
int i1, i2, num, ret, i = 0,zd = 0,s=0;
for (s = 1; s < 10; s++)
{
for (i2 = 0; i2 < 10; i2++)
{
for (i1 = 0; i1 < 10; i1++)
{
for (zd = 0; zd < 10; zd++)
{
num = s * pow(10.0, 6.0) + i2 * pow(10.0, 5.0) + i1 * pow(10.0, 4.0) + zd * pow(10.0, 3.0) + i1 * pow(10.0, 2.0) + i2 * pow(10.0, 1.0) + s;
if (num % 2 == 0)
continue;
else
{
ret = test(num);
if (ret != 0)
{
arr[i] = ret;
i++;
}
}
}
}
}
}
}
void test5(void)
{
int i1, i2, num, ret, i = 0, zd = 0,s=0;
for (s=1; s < 10; s++)
{
for (i1 = 0; i1 < 10; i1++)
{
for (zd = 0; zd < 10; zd++)
{
num = s * pow(10.0, 4.0) + i1 * pow(10.0, 3.0) + zd * pow(10.0, 2.0) + i1 * pow(10.0, 1.0) + s;
if (num % 2 == 0)
continue;
else
{
ret = test(num);
if (ret != 0)
{
arr[i] = ret;
i++;
}
}
}
}
}
}
void test3(void)
{
int num, ret, i = 0, zd = 0,s=0;
for (s=1; s < 10; s++)
{
for (zd = 0; zd < 10; zd++)
{
num = s * pow(10.0, 2.0) + zd * pow(10.0, 1.0) + s;
if (num % 2 == 0)
continue;
else
{
ret = test(num);
if (ret != 0)
{
arr[i] = ret;
i++;
}
}
}
}
}
int main()
{
clock_t start, end;//这里是加了一个计算程序运行时长的功能
double time = 0;
start = clock();
int n,num=1, i, ret;
printf("请输入位数: \n");
scanf("%d", &n);
if (n == 9)
test9();
else if (n == 7)
test7();
else if (n == 5)
test5();
else if (n == 3)
test3();
for (i = 0; arr[i]!=0; i++)
{
printf("%d < ----- %d \n",arr[i],num);
num++;
}
end = clock();
time = end - start;
printf("程序运行时长为 %f ms\n", time);
return 0;
}
可以说效果还是很不错的 也只是上一道题的一点小升级
3.特定条件下的回文素数生成
那么个人觉得有很多细节关于这道题
其中由于我设计的缺点,在对于题干 “依次输出大于M的n个回文素数对” 处理的不好
对于输入的数据必须为 300 1 003 或者是 300 0 003 这样比较干净的,除了中间位数和首尾位有数字的数据比较得心应手
别的像 39993 4989894 这样的起始输入数 我的代码输不出结果
但也不是太弱不禁风,比如 6998996 我也能成功 但我真不知道怎么跑起来的哈哈
用一张图表示就是:
所以它还是跑成功了,我就不敢再改了
代码奉上:
很多无法理解的奇怪语句希望能谅解 我这是第一次写 我还是个傻小白~~~
//#include <stdio.h>
//#include <time.h>
//#include <windows.h>
#include<stdio.h>
#include<math.h>
int z = 0;
int w = 0, s = 0;
int* p = &w;
int* q = &s;
int brr[2] = { 0 };
int arr[100] = { 0 };
int a = 0;
int test(int num)//快速判断素数法
{
double a = num;
if (num == 2 || num == 3)
return num;
if (num % 6 != 1 && num % 6 != 5)
return 0;
double tmp = sqrt(a);
int i = 0;
for (i = 5; i <= tmp; i += 6)
if (num % i == 0 || num % (i + 2) == 0)
return 0;
return num;
}
void swap(void)
{
int i = 0;
if (test(brr[1]) != 0)
{
arr[a] = brr[0];
a++;
arr[a] = brr[1];
a++;
}
for (i = 0; i < 2; i++)
{
brr[i] = 0;
}
}
void test9(int s,int n,int x)
{
int i1, i2, i3, num, ret, i = 0, k = 1,p=0,zd=0;
z++;
again:
if (k == 1)
{
for (i3 = 0; i3 < 10; i3++)
{
for (i2 = 0; i2 < 10; i2++)
{
for (i1 = 0; i1 < 10; i1++)
{
for (zd=z; zd < 9; zd++)
{
num = s * pow(10.0, 8.0) + i3 * pow(10.0, 7.0) + i2 * pow(10.0, 6.0) + i1 * pow(10.0, 5.0) + zd* pow(10.0, 4.0) + i1 * pow(10.0, 3.0) + i2 * pow(10.0, 2.0) + i3 * pow(10.0, 1.0) + s;
if (num % 2 == 0)
continue;
else
{
if (num > x)
{
ret = test(num);
if (ret != 0)
{
brr[0] = num;
brr[1] = num+10000;
swap();
}
}
if (arr[n-1] != 0)
{
k = 0;
goto again;
}
}
}
p++;
if (p == 1)
{
z = 0;
p = 10;
}
}
}
}
}
}
void test7(int s, int n,int x)
{
int i1, i2, num, ret, i = 0, k = 1,zd=0,p=0;
z++;
again:
if (k == 1)
{
for (i2 = 0; i2 < 10; i2++)
{
for (i1 = 0; i1 < 10; i1++)
{
for (zd = z; zd < 10; zd++)
{
num = s * pow(10.0, 6.0) + i2 * pow(10.0, 5.0) + i1 * pow(10.0, 4.0) + zd * pow(10.0, 3.0) + i1 * pow(10.0, 2.0) + i2 * pow(10.0, 1.0) + s;
if (num % 2 == 0)
continue;
else
{
if (num > x)
{
ret = test(num);
if (ret != 0)
{
brr[0] = num;
brr[1] = num+1000;
swap();
}
}
if (arr[n - 1] != 0)
{
k = 0;
goto again;
}
}
}
p++;
if (p == 1)
{
z = 0;
p = 10;
}
}
}
}
}
void test5(int s, int n,int x)
{
int i1, i2, num, ret, i = 0, k = 1, zd = 0,p=0;
z++;
again:
if (k == 1)
{
for (s; s < 10; s++)
{
for (i1 = 0; i1 < 10; i1++)
{
for (zd = z; zd < 10; zd++)
{
num = s * pow(10.0, 4.0) + i1 * pow(10.0, 3.0) + zd * pow(10.0, 2.0) + i1 * pow(10.0, 1.0) + s;
if (num % 2 == 0)
continue;
else
{
if (num > x)
{
ret = test(num);
if (ret != 0)
{
brr[0] = num;
brr[1] = num+100;
swap();
}
}
if (arr[n - 1] != 0)
{
k = 0;
goto again;
}
}
}
p++;
if (p == 1)
{
z = 0;
p = 10;
}
}
}
}
}
void test3(int s, int n,int x)
{
int num, ret, i = 0, k = 1, zd = 0, p = 0;
z++;
again:
if (k == 1)
{
for (s; s < 10; s++)
{
for (zd = z; zd < 10; zd++)
{
num = s * pow(10.0, 2.0) + zd * pow(10.0, 1.0) + s;
if (num % 2 == 0)
continue;
else
{
if (num > x)
{
ret = test(num);
if (ret != 0)
{
brr[0] = num;
brr[1] = num+10;
swap();
}
}
if (arr[n - 1] != 0)
{
k = 0;
goto again;
}
}
}
p++;
if (p == 1)
{
z = 0;
p = 10;
}
}
}
}
void test1(int x, int* p, int* q)//输入数字生成位数
{
double i = 0.0, ret = 0.0;
int num, b = 0, zw = 0;
for (i = 10.0; i >= 0; i--)
{
ret = pow(10.0, i);
num = x / ret;
if (num != 0)
{
b = 1;
}
else
continue;
if (b == 1)
{
break;
}
}
*p = (int)i;
*q = num;
zw = i / 2;
z = (x /pow(10.0,zw));
z = z % 10;
}
int main()
{
//clock_t start, end; 解开此处代码以及上端库函数的注释 即可计算程序运行时长
//double time = 0;
//start = clock();
int n, m, i, ret;
scanf("%d%d", &n, &m);
test1(n, p, q);//此时w表示n 有几个 0
w = w + 1;//这里是指 n 有几个数字组成
if (w == 9)
test9(s, m * 2, n);
else if (w == 7)
test7(s, m * 2, n);
else if (w == 5)
test5(s, m * 2, n);
else if (w == 3)
test3(s, m * 2, n);
for (i = 0; i < m * 2 - 1; i++)
{
printf("%d %d\n", arr[i], arr[i + 1]);
i++;
}
//end = clock();
//time = end - start;
//printf("程序运行时长为 %f ms\n", time);
return 0;
}
这里设置swap函数的理由:
设置 goto语句是为了在收集到足够的回文素数对后快速跳出来 结束运算
总结
这种题目还是挺有意思的,我能力有限,只能如此踉踉跄跄的写完,如果有更好想法的朋友,欢迎联系,我将抱着学习的心态和你进一步讨论交流。