Palindromic Primes

14 篇文章 0 订阅
1 篇文章 0 订阅

Palindromic Primes Category in Jeopardy!

问题描述

Prime numbers are defined as follows: a number is prime if it is greater than 1 and is evenly divisible only by itself and 1. Note that by definition neither zero nor one is a prime number.
A palindromic number is one whose string representation is a palindrome, that is, a string that reads the same backwards and forwards.
You are on the clue crew preparing questions for the category “Palindromic Primes” and are to write a program to generate the answer and responding question in Jeopardy! style.

输入

The input file contains a series of number pairs (with white space separating them) specifying individual problems, ending with a pair of zeroes. The first number gives the number of digits for the numbers to be considered, the second number gives the base in which the numbers are to be generated. The numbers are separated by a single space. You are assured that all palindromic primes for this problem can be represented in the range of a standard 32-bit signed integer. The bases allowed are integer bases between 2 and 36 — with bases above base ten handled as extensions of hexadecimal. This means that the valid numeric digits are in the range [‘0’…‘9’] and [‘a’…‘z’].

输出

For each number, generate one line giving the number of digits and the base as the answer and then on the next line the number of palindromic primes found as the question as shown in the sample output. Each output pair should be separated by a blank line.

Sample Input

1 10 
2 10 
3 10 
4 24 
5 4 
0 0

Sample Output

The number of 1-digit palindromic primes < 2^31 in base 10. 
What is 4? 

The number of 2-digit palindromic primes < 2^31 in base 10. 
What is 1? 

The number of 3-digit palindromic primes < 2^31 in base 10. 
What is 15? 

The number of 4-digit palindromic primes < 2^31 in base 24. 
What is 0? 

The number of 5-digit palindromic primes < 2^31 in base 4. 
What is 10?

题目大意

定义了一种特殊的数字叫做回文素数。
比如11 就是一个回文素数。但是这题并不是就这么轻易放弃折腾你的。
他还定义了一种叫做不同进制下的回文素数。这个进制最多到36进制。
比如ZXZ就是一个回文数。这个数实际上只有三位,千万不要往十进制上靠。
他还规定了这个回文素数的长度是多少位哦!

思路解析

那么说一下解题思路。
我们可以构造回文数字的一半,另外一半自然而然就知道了。
比如12321我们可以构造123另一半是21
因为这个数字是递增的。小于和大于都不是要的范围。只有一段区间有效。
我们直接暴力跑出他的所有就可以了,当然如果超过1e31自然而然的退出。
第二步,我门需要把构造的回文数转换成十进制用素数探测法,其实就是米勒罗宾算法
米勒罗宾大致的操作为,利用费马定理来验证是否为质数,每一次错误概率大概是0.25左右,重复多次探测即可将错误概率压到最小。

Accepted Code

//#include<unordered_map>
#include<algorithm>
#include<iostream>
#include<string.h>
#include <iomanip>
#include<stdio.h>
#include<vector>
#include<string>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll ll_inf = 9223372036854775807;
const int int_inf = 2147483647;
const short short_inf = 32767;
const ll less_inf = 0x3f3f3f3f;
const char char_inf = 127;
#pragma GCC optimize(2)
#define accelerate cin.tie(NULL);cout.tie(NULL);ios::sync_with_stdio(false);
#define PI 3.141592653589793
#define EPS 1.0e-8
ll gcd(ll a, ll b) {
	return b ? gcd(b, a % b) : a;
}
ll lcm(ll a, ll b) {
	return a / gcd(a, b) * b;
}
inline ll read() {
	ll c = getchar(), Nig = 1, x = 0;
	while (!isdigit(c) && c != '-')c = getchar();
	if (c == '-')Nig = -1, c = getchar();
	while (isdigit(c))x = ((x << 1) + (x << 3)) + (c ^ '0'), c = getchar();
	return Nig * x;
}
inline void out(ll a) {
	if (a < 0)putchar('-'), a = -a;
	if (a > 9)out(a / 10);
	putchar(a % 10 + '0');
}
ll qpow(ll x, ll n, ll mod) {
	ll res = 1;
	while (n > 0) {
		if (n & 1)res = (res * x) % mod;
		x = (x * x) % mod;
		n >>= 1;
	}
	return res;
}
#define read read()

ll qmul(ll x, ll y, ll mod) {
	return (x * y - (long long)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}
bool Miller_Rabin(ll p) {
	ll prime[] = { 2, 3, 5, 233, 331 };
	if (p < 2 || p != 2 && p % 2 == 0) return false;
	ll s = p - 1;
	while (!(s & 1)) s >>= 1;
	for (int i = 0; i < 5; i++) {
		if (p == prime[i]) return true;
		ll t = s, m = qpow(prime[i], s, p);
		while (t != p - 1 && m != 1 && m != p - 1)
			m = qmul(m, m, p), t <<= 1;
		if (m != p - 1 && !(t & 1)) return false;
	}
	return true;
}
char mark[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char now[100];
int n, m;
bool sw;
bool can;
bool sw2;
void change(int num)
{
	int base = m;
	char temp[100];
	int cnt = 0;
	while (num)
	{
		temp[cnt++] = mark[num % base];
		num /= base;
	}
	if ((n & 1))
	{
		if (cnt * 2 - 1 != n)
		{
			if (can)sw2 = false;
			sw = false;
			return;
		}
	}
	else
	{
		if (cnt * 2 != n)
		{
			if (can)sw2 = false;
			sw = false;
			return;
		}
	}
	can = true;
	for (int i = 0; i < cnt; i++)
		now[i] = temp[cnt - 1 - i];
	if (cnt * 2 == n)
	{
		int j = cnt;
		for (int i = 0; i < cnt; i++, j++)
			now[j] = temp[i];
		now[j] = 0;
	}
	else
	{
		int j = cnt;
		for (int i = 1; i < cnt; i++, j++)
			now[j] = temp[i];
		now[j] = 0;
	}
}
int main()
{
	int CNT = 0;
	while (scanf("%d%d", &n, &m) != EOF)
	{
		if (n == 0 && m == 0)break;
		if (CNT++)puts("");
		int res = 0;
		can = false;
		sw2 = true;
		for (int i = 1; sw2 && i <= 100000000; i++)
		{
			sw = true;
			change(i);
			if (sw)
			{
				ll val = 0;
				for (int j = 0; j < n; j++)
				{
					char t = now[j];
					if (t <= '9')t -= '0';
					else t = t - 'A' + 10;
					val += ll(t) * qpow(m, j, ll_inf);
				}
				if (val < (1ll << 31) && Miller_Rabin(val))res++;
			}
		}
		printf("The number of %d-digit palindromic primes < 2^31 in base %d.\n", n, m);
		printf("What is %d?\n", res);
	}
}

By-Round Moon

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Round moon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值