题解
2024-02-29 13:37:51
发布于:广东
40阅读
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







有帮助,赞一个