UVA967的题解

发布时间 2023-08-29 20:35:45作者: osfly

\(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;
}