51nod 2378 最后一次
题目背景跟最后一次半毛钱关系都没有
题目
牛牛最近学习了质数的概念。
质数指在大于1的自然数中,除了1和它本身以外不再有其他因数。
输入一个n,输出小于等于n最大的质数。
数据范围:
对于所有数据: 2 <= n <= 1000000000000
30分: n <= 100000
70分: n <= 1000000000
输入样例:
100
输出样例:
97
思路
完全不要被 1 0 12 10^{12} 1012吓到,int就可以过。
我们知道
1
0
12
10^{12}
1012 =
1
0
6
10^{6}
106
×
\times
×
1
0
6
10^{6}
106,
对于大于
1
0
6
10^{6}
106的合数
x
x
x,
一定可以分解为
一个小于
1
0
6
10^{6}
106的质数
a
a
a 和 一个大于
1
0
6
10^{6}
106的质数或合数
b
b
b。
所以我们把小于
1
0
6
10^{6}
106的质数全部用欧拉筛找出来,然后一个个判断就好了,具体看代码注释。
代码
#include <cstring>
#include <iostream>
using namespace std;
const int N = 1e6 + 5;
int cnt;//质数个数
int pr[N];//质数 prime
int vis[N];//标记质数
long long n;//输入还是要long long的
void euler() {
//欧拉筛模板
vis[1] = true;
for (int i = 2; i <= N; i++) {
if (!vis[i]) pr[++cnt] = i;
for (int j = 1; j <= cnt; j++) {
if (i * pr[j] > N) break;
vis[i * pr[j]] = true;
if (i % pr[j] == 0) break;
}
}
}
int main() {
scanf("%lld", &n);
euler();
for (long long i = n; ; i--) {//从 n 开始一个一个往下减
bool f = true;//用 f 来判断 i 是否为质数
for (int j = 1; j<=cnt and pr[j] < i; j++) {//小于10^6的质数
/*
讲一下 pr[j] < i
若 i 本身就是小于10^6的质数
到 ↓ 这个判断就会出错 所以加上 pr[j] < i
*/
if (i % pr[j] == 0 ) {
f = false;
break;
}
}
if (f) {//扫完一遍都没有质因子则输出
printf("%lld", i);
exit(0);
}
}
return 0;
}
留个赞再走嘛(´▽`ʃ♡ƪ)