CF 568A
题目链接:
http://codeforces.com/problemset/problem/568/A
题意:
设A(n),B(n)分别表示前n个数中素数个数、回文数个数。
问最大n满足A(n) <= p / q * B(n)
思路:
看到题解我一脸日了狗的表情+_+
最大数1300000,然后从大到小枚举。
因为前n数种素数数量增长速度远大于前n个数中回文数的数量,而对于n=1时素数个数为0,回文数为1,所以不存在不合法情况。
源码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
#define LL long long
const int MAXN = 1300001;
int prime[MAXN], vis[MAXN];
int lv1[MAXN], lv2[MAXN];
bool valid(int a)
{
int t1 = a;
int t2 = 0;
while(a){
t2 = t2 * 10 + a % 10;
a /= 10;
}
if(t1 == t2)
return true;
return false;
}
void init()
{
memset(vis, 0, sizeof(vis));
memset(prime, 0, sizeof(prime));
for(int i = 2 ; i < MAXN ; i++){
if(vis[i] == 0){
prime[i] = 1;
for(int now = i ; now < MAXN ; now += i)
vis[now] = 1;
}
}
lv1[1] = 0;
lv2[1] = 1;
for(int i = 2 ; i < MAXN ; i++){
lv1[i] = lv1[i - 1];
lv2[i] = lv2[i - 1];
if(prime[i]) lv1[i]++;
if(valid(i)) lv2[i]++;
}
}
int main()
{
init();
int p, q;
while(scanf("%d%d", &p, &q) != EOF){
for(int i = MAXN - 1 ; i >= 1 ; i--){
if((LL)q * lv1[i] <= (LL)p * lv2[i]){
// if(i == 36){
// printf("lv1[%d] = %d, lv2[%d] = %d\n", i, lv1[i], i, lv2[i]);
// printf("p = %d, q = %d\n", p, q);
// }
printf("%d\n", i);
break;
}
}
}
return 0;
}