Project-Euler-035线性筛

035题:

题意:

​ 197被称为圆周素数,因为将它逐位旋转所得到的数:197,719和971都是素数。

​ 小于100的圆周素数有十三个:2、3、5、7、11、13、17、31、37、71、73、79和97。

​ 小于一百万的圆周素数有多少个?

思路:

​ 如果1~1000000所有数都逐位旋转复杂度太高,所以应该用线性筛筛选出全部的素数。

​ 对于怎么逐位旋转,我们可以依据以下三点:

​ 1.通过(int)log10(n) + 1来求n的位数

​ 2.利用 n = n / 10 + (n % 10) * pow(10, (int)log10(n)) 来得到逐位旋转的值

​ 3.利用线性筛使用的bool数组来判断逐位旋转的值是否位素数

​ 看到这题网上有些人写了两百多行代码并且时间复杂度还高,觉得利用上述三点就可以缩短代码长度并提高运行效率~

代码:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <inttypes.h>
#define d int32_t
#define ll int64_t
#define mem(a) memset(a, 0, sizeof(a));
#define N 1000000

d ans;            //存储满足条件的个数
d prime[N + 5];   //筛选出100万内的全部素数,其中prime[0]为这些素数的个数
bool book[N + 5]; //book[i]代表i是否为素数(0是,1不是)

//初始化和预处理100万内的全部素数
void init() {
    mem(prime);
    mem(book);
    ans = 0;
    for (d i = 2; i < N; i++) {
        if (!book[i]) {
            prime[++prime[0]] = i;
        }
        for (d j = 1; j <= prime[0] && prime[j] * i < N; j++) {
            book[prime[j] * i] = 1;
            if (i % prime[j] == 0) break;
        }
    }
}

//判断素数t是否满足条件
bool chooes (d t) {
    d len = (int)log10(t);
    d maxx = (int)pow(10, len);
    for (d i = 0; i < len; i++) {
        if (t % 10 == 0) {
            return 0;
        }
        t = t / 10 + (t % 10) * maxx;
        if (book[t]) return 0;
    }
    return 1;
}

//遍历全部素数
void work() {
    for (d i = 1; i <= prime[0]; i++) {
        d t = prime[i];
        if (chooes (t)) ans++;
    }
}

d main() {
    init();
    work();
    printf("%" PRId32"\n", ans);
    return 0;
}

最后答案是 55

转载请注明出处!!!

如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值