题解
2024-02-29 13:37:51
发布于:广东
28阅读
0回复
0点赞
本来是想用埃式筛完成的,结果超时了,所以不得已用了些卑鄙的手段(
原写法↓
#include <iostream>
#include <cstdio>
using namespace std;
bool vis[100000005];
int pow(int n){
int ct = 1;
while(n--) ct *= 10;
return ct;
}void _init(int n){
vis[1] = 1;
for(int i = 2; i * i <= n; i++){
if(!vis[i]){
for(int j = i * 2; j <= n; j += i){
vis[j] = 1;
}
}
}
}bool check(int x){
while(x){
if(vis[x]) return 0;
x /= 10;
}return 1;
}
int main(){
int n;
cin >> n;
int x = pow(n);
_init(x);
for(int i = x / 10; i < x; i++){
if(check(i)) printf("%d\n", i);
}
return 0;
}
发现时间怎么压也压不下去,看了看别人的,然后写出来↓
#include <iostream>
#include <cstdio>
using namespace std;
//bool vis[100000005];
int n, x;
int pow(int n){//pow
int ct = 1;
while(n--) ct *= 10;
return ct;
}
int check(int i){
int flag = -1;
int ct = x;
for(; ct; ct /= 10){
int j = i / ct;//初始化j,因为for的开始定下来就不能改的,所以得在循环内加
if(j == 1) flag = ct;
for(int k = 2; k * k <= j; k++){//判断是不是质数
if(j == 2) break;
if(j % k == 0){
flag = ct;
break;
}
}if(flag != -1) return flag;//如果flag不是-1就代表有合数出现
}return -1;
}
int main(){
cin >> n;
x = pow(n);
for(int i = x / 10; i < x; i++){
int flag = check(i);
if(flag == -1) printf("%d\n", i);//如果flag仍然是-1的话,那这就是质数花瓣
else i = (i / flag + 1) * flag - 1;//最关键的一步!!!决定你的成败!否则的话就跳到下一个可能是质数花瓣的数,极大地减少了时间,不用一个一个枚举
}
return 0;
}
这跳过真的是天才()
原理:如果遍历到第n位是合数,则以后的前面是那个数的都不行,要跳过。
比如:
7513
遍历到第2位75是合数,那后面的7514-7599就绝对不是质数花瓣
全部评论 1
等等……深搜?
2024-02-29 来自 广东
0
有帮助,赞一个