题目 | Primes or Palindromes
Codeforces Round 315 (Div. 1)
A. Primes or Palindromes?
https://codeforces.com/contest/568/problem/A
3 seconds / 256 megabytes
standard input / standard output
Problem
Rikhail Mubinchik believes that the current definition of prime numbers is obsolete as they are too complex and unpredictable. A palindromic number is another matter. It is aesthetically pleasing, and it has a number of remarkable properties. Help Rikhail to convince the scientific community in this!
Let us remind you that a number is called prime if it is integer larger than one, and is not divisible by any positive integer other than itself and one.
Rikhail calls a number a palindromic if it is integer, positive, and its decimal representation without leading zeros is a palindrome, i.e. reads the same from left to right and right to left.
One problem with prime numbers is that there are too many of them. Let's introduce the following notation: π(n) — the number of primes no larger than n, rub(n) — the number of palindromic numbers no larger than n. Rikhail wants to prove that there are a lot more primes than palindromic ones.
He asked you to solve the following problem: for a given value of the coefficient A find the maximum n, such that π(n) ≤ A·rub(n).
Input
The input consists of two positive integers p, q, the numerator and denominator of the fraction that is the value of A (, ).
Output
If such maximum number exists, then print it. Otherwise, print "Palindromic tree is better than splay tree" (without the quotes).
Examples
Input
1 1
Output
40
Input
1 42
Output
1
Input
6 4
Output
172
题解
本题很重要的一点是:质数的增长速度远快于回文数的增长速度。
下图绘制了 $1\sim 10000$ 的质数和回文数的数量的增长速度情况,通过观察可见质数的数量增长得更快。
如果要更准确得描述的话,质数数目的增长情况可以近似为:
$$ \pi(x)\sim \frac{x}{\log x} $$
根据该近似函数,可以知道随着数字的增大,素数的密度逐渐降低。这个其实就是数论中的素数定理.
而回文数的增长速度削减得非常快,在 $9\to 10,\;999\to1000,\;99999\to100000\dots$ 的位置会有一个斜率缩小约 $10$ 倍的拐点,从上图中也能发现 $10$ 和 $1000$ 处的拐点。
综上,回文数的密度降低速度是指数级别的,而质数的密度降低速度是对数级别的。而本题给出的 $A$ 相当于一个放缩参数,范围是缩小 $42$ 倍到放大 $42$ 倍,这个范围非常小。即使把回文数放大最大 $42$ 倍,它也会很快被质数超过,因此解的上限其实很低。
实际测试中,解不会大于 $2\cdot10^6$,因此直接预处理 $1\sim2\cdot10^6$ 的质数和回文数即可。质数的初始化可用筛法完成,复杂度 $O(n)$,回文数的初始化直接最朴素的方法即可,复杂度 $O(n\lg n)$.
代码
#include <bits/stdc++.h>
#define endl '\n'
// #define int long long
using namespace std;
constexpr int MAXN = 2e6 + 10;
bool not_prime[MAXN];
int prime[MAXN], prime_cnt[MAXN], prime_size;
void init_prime()
{
not_prime[0] = not_prime[1] = true;
for (int i = 2; i < MAXN; i++)
{
prime_cnt[i] = prime_cnt[i - 1];
if (!not_prime[i])
{
prime[prime_size++] = i;
prime_cnt[i]++;
}
for (int j = 0; j < prime_size && i * prime[j] < MAXN; j++)
{
not_prime[i * prime[j]] = true;
if (i % prime[j] == 0)
break;
}
}
}
bool check_palindromes(int x)
{
vector<int> digit;
while (x)
{
digit.push_back(x % 10);
x /= 10;
}
for (int i = 0, j = digit.size() - 1; i <= j; i++, j--)
if (digit[i] != digit[j])
return false;
return true;
}
int palindromes_cnt[MAXN];
void init_palindromes()
{
for (int i = 1; i < MAXN; i++)
palindromes_cnt[i] = palindromes_cnt[i - 1] + check_palindromes(i);
}
void solve()
{
init_prime();
init_palindromes();
int p, q;
cin >> p >> q;
for (int i = MAXN - 1; i >= 0; i--)
{
if (prime_cnt[i] * q <= palindromes_cnt[i] * p)
{
cout << i << endl;
return;
}
}
cout << "Palindromic tree is better than splay tree" << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin >> t;
while (t--)
solve();
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi