【水】16进制对称素数

题目描述
如果一个素数转换成十六进制后是“对称”的,我们将其称为“十六进制对称素数”,例如17(11H)就是一个“十六进制对称素数”,而19(13H)虽然是素数但十六进制并不“对称”。
试统计在[n,m]范围内有多少素数是“十六进制对称素数”。
输入
两个整数n和m
输出
范围内“十六进制对称素数”的个数

思路:使用构造法先构造16进制的数,在进行素性判断即可

#pragma GCC optimize(3)
#pragma comment(linker,"/STACK:102400000,1024000")
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'

#define N 200200
long long int huiwen[N] = { 0 };	//回文数个数小于200000-1

/*构造16进制回文数组*/
void palindrome()
{
	for (int j = 0; j <= 15; j++)
	{
		huiwen[j] = j;
	}
	long long int newed, x, i;	//i作为循环变量
	int n = 0;//x在十六进制下是几位数
	int count = 0x10;
	for (i = 1; i <= 0xffff; i++)
	{
		newed = 0;
		x = i;
		n = 0;
		do
		{
			newed = newed * 16 + x % 16;	//将x在16进制下倒序
			x /= 16;
			n++;
		} while (x > 0);
		huiwen[count++] = pow(16, n) * i + newed;	//偶数位(2*n)回文数
		if (i <= 0xfff)
			for (int k = 0; k <= 15; k++)	//注意是15 
			{
				huiwen[count++] = pow(16, n + 1) * i + pow(16, n) * k + newed;	//奇数位(2*n+1)回文数
			}
	}
}

/*判断质数部分*/
/* c 考虑到a * b可能溢出,改为计算 (a * b) % c */

long long mulmod(long long a, long long b, long long mod)
{
	long long x = 0, y = a % mod;
	while (b > 0)
	{
		if (b % 2 == 1)
		{
			x = (x + y) % mod;
		}
		y = (y * 2) % mod;
		b /= 2;
	}
	return x % mod;
}

/*蒙哥马利算法(模幂运算) */
long long modulo(long long base, long long exponent, long long mod)
{
	long long x = 1;
	long long y = base;
	while (exponent > 0)
	{
		if (exponent % 2 == 1)
			x = (x * y) % mod;
		y = (y * y) % mod;
		exponent = exponent / 2;
	}
	return x % mod;
}


/*米勒-拉宾素数检测,不确定算法,迭代次数越多越准确*/
bool Miller(long long p, int iteration)
{
	if (p < 2)
	{
		return false;
	}
	if (p != 2 && p % 2 == 0)
	{
		return false;
	}
	long long s = p - 1;
	while (s % 2 == 0)
	{
		s /= 2;
	}
	for (int i = 0; i < iteration; i++)
	{
		long long a = rand() % (p - 1) + 1, temp = s;
		long long mod = modulo(a, temp, p);
		while (temp != p - 1 && mod != 1 && mod != p - 1)
		{
			mod = mulmod(mod, mod, p);
			temp *= 2;
		}
		if (mod != p - 1 && temp % 2 == 0)
		{
			return false;
		}
	}
	return true;
}

bool pri(long long int n)
{
	int iteration = 5;//迭代次数 
	if (Miller(n, iteration))
		return true;
	else
		return false;
}


/*主函数:遍历回文数会超时,使用构造法创造回文数*/
signed main()
{
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	long long int i;									//i为循环变量
	long long int num = 0, n, m;			//1 < n < m < 2 ^ 32,num计数用
	memset(huiwen, 0, sizeof(huiwen));
	palindrome();
	cin >> n >> m;
	for (i = 1; i < N; i++)
	{
		if (huiwen[i] <= m && huiwen[i] >= n && pri(huiwen[i]) == true)
		{
			num++;
		}
	}
	cout << num << endl;
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值