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
如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢