设 \(check_i\) 为 \(1\sim n\) 中满足题意的数的数量。
显然答案为 \(check_j-check_{i-1}\)。
注意到 \(check\) 能直接暴力求出来。
那么就可以先把 \(10^6\) 范围内的所有质数求出来,然后所有数跑一遍,每个数都去旋转得出所有数后判断是否均为质数,记录下来。
代码很好写。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define ull unsigned long long
#define INF 1e9
#define eps 1e-15
using namespace std;
const int N=1e7+10;
const int M=1e6+10;
const ll mod=998244353;
int n,m,q,T;
int vis[N];
int prime[N],cnt;
int check[N];
int num[10],tot;
int pre[N];
int calc(int x)//计算位数
{
int res=0;
while(x)
{
res++;
x/=10;
}
return res;
}
int rotate(int x,int ws)
{
int qwq=1;
for(int i=1;i<ws;i++) qwq*=10;
int p=x%10;
x/=10;
return p*qwq+x;
}
void make(int x,int ws)
{
tot=0;
for(int i=1;i<=ws;i++)
x=rotate(x,ws),num[++tot]=x;
}
bool judge()
{
for(int i=1;i<=tot;i++)
if(vis[num[i]]) return 0;
return 1;
}
void init()
{
for(int i=2;i<=N;i++)
{
if(!vis[i]) prime[++cnt]=i;
for(int j=1;j<=cnt&&i*prime[j]<=N;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
for(int i=1;i<=1e6;i++)
{
if(check[i]) continue;
make(i,calc(i));
if(judge())
for(int j=1;j<=tot;j++) check[num[j]]=1;
}
for(int i=1;i<=1e6;i++) pre[i]=pre[i-1]+check[i];
}
signed main()
{
init();
int x,y;
while(scanf("%d",&x)&&x!=-1)
{
scanf("%d",&y);
int ans=pre[y]-pre[x-1];
if(!ans) printf("No Circular Primes.\n");
else if(ans==1) printf("1 Circular Prime.\n");
else printf("%d Circular Primes.\n",ans);
}
return 0;
}
标签:10,UVA967,题解,long,int,res,check,define
From: https://www.cnblogs.com/osfly/p/17665777.html