洛谷 P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib

传送门

看到题解里边都是些什么鬼东西,然后我就来发着篇题解了,都是些什么群魔乱舞

首先这个题我用的欧拉筛做的,然后欧拉筛是什么:

\(\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;
}
posted @ 2019-08-01 16:19  Kersen  阅读(198)  评论(0编辑  收藏  举报