传送门
看到题解里边都是些什么鬼东西,然后我就来发着篇题解了,都是些什么群魔乱舞
首先这个题我用的欧拉筛做的,然后欧拉筛是什么:
在 \(\omicron\)(n) 的时间复杂度内筛出质数与积性函数的优秀算法
每一个合数都被它的最小质因子筛掉.
对于每一个i,从小到大枚举当前得到的所有质数p,那么$p \times i $ 一定不是质数(显然),然后枚举到\(p | i\) 为止。
我们假设n的最小质因子是q,那么当 i = $\frac{a}{b} $ , p = q时,n才会被筛掉(显然).
这样每一个数之会被筛掉一次,所以时间复杂度是\(\omicron\)(n)的.
code:
void shai(int s) {
b[1] = 1;
for (int i = 2; i <= s; i++) {
if (!b[i]) prime[++num] = i;
for (int j = 1; j <= num; j++) {
if (prime[j] * i >= s) break;
b[prime[j] * i] = 1;
if (i % prime[j] == 0) break;
}
}
}
那么这个题应该怎么用欧拉筛来做呢?
因为我们如果每次都判断一个数是不是质数,那么欧拉筛筛出来之后判断就成了\(\omicron\)(n)的,所以我是先把素数都筛出来,然后判断就行了啊...QwQ
因为最后一个点是\(n = 8\)的,很明显过不了啊,咋办???
希望大家心里永远都存在一句话:打表出省一!
我们就先把$ n = 8 \(时的解求出来就行了啊,反正\) n = 8 $的时候解也不多
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#define N 100010
#define M 1010
using namespace std;
int prime[1000010];
int n, num;
bool b[10000010];
int read() {
int s = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
return f ? -s : s;
}
void shai(int s) {
b[1] = 1;
for (int i = 2; i <= s; i++) {
if (!b[i]) prime[++num] = i;
for (int j = 1; j <= num; j++) {
if (prime[j] * i >= s) break;
b[prime[j] * i] = 1;
if (i % prime[j] == 0) break;
}
}
}
bool pd(int x) {
for (int i = 1; i <= n; i++) {
if (b[x] == 1) return 0;
x = x / 10;
}
return 1;
}
int main() {
n = read();
if (n == 8) {
puts("23399339");
puts("29399999");
puts("37337999");
puts("59393339");
puts("73939133");
return 0;
}
int m = 1;
for (int i = 1; i <= n; i++) m *= 10;
shai(m);
for (int i = m / 10; i < m; i++) {
if (pd(i) == 1) printf("%d\n", i);
}
return 0;
}