欧拉计划 第三十五题

The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.

Find the sum of the only eleven primes that are both truncatable from left to right and right to left.

NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.

3797号有一个有趣的财产。作为素数本身,可以从左到右连续删除数字,并在每个阶段保持素数:3797,797,97和7.同样,我们可以从右到左工作:3797,379,37和3。

找到从左到右和从右到左都可截断的仅有的11个素数之和。

注意:2,3,5和7不被认为是可截断的素数。

思考

1.线性筛实现将素数标记出来,所有素数放在prime[i]的数组前半部分中;

2.是否满足奇怪数字的条件:(1)依次删除末位数 n/10;(2)依次删除首位数 n -= (n%dh)*dh;

3.在素数数组中判断满足条件的数字,并将其加到累加器sum中。

注意:由1开头和结尾的素数都不满足题意,因为1不是素数
#include <stdio.h>
#include <math.h>

#define max 1000000
 
int prime [max + 5] = {0};
int isprime[max + 5] = {0};

void Prime(){ 
	for(int i = 2; i < max; i++){
		if(!prime[i]) {prime[++prime[0]] = i;}
		for(int j = 1; j <= prime[0]; j++){
			if(prime[j] * i > max) break;
			prime[prime[j] * i] = 1;
			isprime[prime[j] * i] = 1; 
			if(i % prime[j] == 0) break;
		}
	}
}

int isnum(int x){
	int num = x;
	if(isprime[x] != 0) return 0;//数字本身就不是素数,可省去后面步骤,直接return 0;
	if(x % 10 == 1) return 0;//除掉由1开头的数字;
	while(x){
		x /= 10;
		if(isprime[x] != 0) return 0;//prime数组中前半部分已经放入了素数,再次判断是否为素数,用isprime;
	}//每次删除末位;
	int dh = pow(10, floor(log10(num)));
	if(num / dh == 1) return 0;//除掉由1结尾的数字;
	while(num){
		num -=(num / dh) * dh;
		dh /= 10;
		if(isprime[num] != 0) return 0;
	}//每次删除首位;
	return 1;
}

int main(){
	Prime();
	int flag = 11;
	int sum = 0;
	for(int i = 5; flag != 0; i++){
		if(isnum(prime[i])){
			flag--;
			sum += prime[i];
			printf("%d\n", prime[i]);
		}
	}
	printf("%d\n", sum);
	
	return 0;	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值