幸運數--藍橋杯歷屆試題本科B組Java題--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)。
樣例輸入1
1 20
樣例輸出1
5
樣例輸入2
30 69
樣例輸出2
8

/*
思路:求幸運數區間的個數,其實難度並不難,直接暴力就行,正所謂暴力藍橋杯
我們直接直接計算,1到n的數字即可,然後我們開始篩選,因爲我們記錄的數字直接從第二次篩選結束的,所以我們直接從第三遍篩選開始即可。
每次要除的數字,是上一個幸運數,切記這一條!(本人開始,審題不清,以爲是質數,結果,此處略去罵人十萬字)
記錄下要去除數字的下標
前移即可!
最後輸出。

切記:篩選每次除的數字都是上一個幸運數
注意區間,不包含
*/

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int m, n;
int len = 0;
int main()
{
	scanf("%d %d", &m, &n);
	vector <int> vc(n);
	//下標從1開始
	for (int i = 1; i < n; i++)	vc[i] = 2 * i - 1;//記錄下第2個幸運數產生後的結果即可,節約運算
	int divided = 2;
	len = n;
	for (int select = 3; ; ++select)
	{
		divided = vc[select-1];//除數是上一個幸運數
		
		int num = 1;
		for (int i = 1; i < len; i++)
			if (i%divided != 0)
				vc[num++] = vc[i];//vc重新賦值,覆蓋
		len = num;//長度記錄

		if (vc[select] > n) break;

	}

	int count = 0;
	for (int i = 1; i < n; i++)
	{
		if (vc[i] >= n)	break;
		if (vc[i] < n && vc[i] > m) {
			++count;
		}
	}
	printf("%d", count);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章