蓝桥杯2013年第四届真题-幸运数(C语言)

题目描述

幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的“筛法”生成 
。  
首先从1开始写出自然数1,2,3,4,5,6,.... 
1  就是第一个幸运数。 
我们从2这个数开始。把所有序号能被2整除的项删除,变为: 
1  _  3  _  5  _  7  _  9  .... 
把它们缩紧,重新记序,为: 
1  3  5  7  9  ....  。这时,3为第2个幸运数,然后把所有能被3整除的序号位置的数删去。注意,是序号位置,不是那个数本身能否被3整除!!  删除的应该是5,11,  17,  ... 
此时7为第3个幸运数,然后再删去序号位置能被7整除的(19,39,...) 
最后剩下的序列类似: 
1,  3,  7,  9,  13,  15,  21,  25,  31,  33,  37,  43,  49,  51,  63,  67,  69,  73,  75,  79,  ... 

输入格式

输入两个正整数m  n,  用空格分开  (m  <   n  <   1000*1000)  

输出格式

程序输出  位于m和n之间的幸运数的个数(不包含m和n)。  

样例输入

30 69  

样例输出

8

思路

先设一个自然数数组,再从头开始减去对应的幸运数和他的倍数的下标,组成新的数组

当这次的幸运数在m和n之间时就增加数字,减到n时记录数字个数

幸运数字1的情况单独设立,把所有偶数全部删去

#include<stdio.h>

int luckynum(int a[], int n, int num) {//减去幸运数
	int k = a[num];//幸运数对应的下标
	int right = 0;//舍去的幸运数
	int i;
	for (i = num;i + right < n;i++) {//从当前幸运数开始
		if ((i + right) % k == 0) {//幸运数的倍数下标
			right++;
		}
		if (i + right >= n)
			break;
		a[i] = a[i + right];//赋值
	}
	return i;
}

int main() {
	int m, n;
	int i;
	scanf("%d %d", &m, &n);

	int a[1000000] = { 0 };
	for (i = 0;i <= n;i++) {//自然数
		a[i] = i;
	}
	int score = 0;
	if (m < 1 && n>1)//1在m和n之间
		score++;
	int N = n / 2 + 1;//a[]的总数
	for (i = 1;i < N ;i++) {//幸运数字1
		a[i] = 2 * i - 1;
	}
	for (i = 2;i < N;i++) {
		if (a[i] >= n)
			break;
		if (a[i] > m && a[i] < n)//幸运数在范围内
			score++;
		int k = luckynum(a, N, i);
		N = k;
	}
	printf("%d\n", score);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值