题意:给一个p和q然后求π(n)?≤?p/q*rub(n),的最大的n值,其中π(n)?表示从1到n之间的素数的个数,
rub(n)表示从1到n之间的回文数的个数(回文数不能有前导0,且从左到右和从右到左一样)
分析:其实这题没有题目没有确定n的范围让人不敢直接暴搜打表,但是你只要手动写个函数y=π(n)?/rub(n)
手动模拟暴力一下就可以发现其实这个函数大概是先下降后上升的,由于1/42<=p/q<=42,也就是说当y=42的时候就
是它的边界了,那么n的范围大概是1200000左右,取大一点也无所谓,不要超过1千万就可以
附上代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int maxn = 1.2e6+5; int p[maxn]; int vis[maxn]; int r[maxn]; int dig[100]; int ver(int n){ //求i的回文数 int sum=0; int cnt=0; while(n){ dig[++cnt]=n%10; n=n/10; } int f=1; for(int i=cnt;i>=1;i--){ sum+=dig[i]*f; f*=10; } return sum; } int table1(int n){ //素数打表 int cnt=0; for(int i=2;i<=n;i++) { if(!vis[i]){ p[i]=++cnt; for(int j=i;j<=n;j+=i) vis[j]=1; } } cnt=0; for(int i=1;i<=n;i++){ if(p[i]>cnt) cnt=p[i]; else p[i]=cnt; } } int table2(int n){ //回文打表 int cnt=0; for(int i=1;i<=n;i++){ r[i]=cnt; if(i%10==0) continue; if(ver(i)==i) r[i]=++cnt; } } int main() { int a,b; memset(vis,0,sizeof(vis)); table1(maxn-1); table2(maxn-1); while(scanf("%d%d",&a,&b)!=EOF){ int k=0; for(int i=maxn-1;i>=1;i--){ if(p[i]<=1.0*a/b*r[i]){ k=i; break; } } if(k) printf("%d\n",k); else printf("Palindromic tree is better than splay tree\n"); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-21 13:28:17