2019年第十屆藍橋杯【C++省賽B組】【第四題: 數的分解】——附解題思路及代碼

藍橋杯歷屆題目及解析彙總(附思路及代碼)【點擊此進入】


藍橋杯,ACM算法學習【文檔】【視頻】大放送【點擊此進入】


第四題

標題: 數的分解(本題總分:10 分)

【問題描述】
把 2019 分解成 3 個各不相同的正整數之和,並且要求每個正整數都不包
含數字 2 和 4,一共有多少種不同的分解方法?
注意交換 3 個整數的順序被視爲同一種方法,例如 1000+1001+18 和
1001+1000+18 被視爲同一種。
【答案提交】
這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果爲一
個整數,在提交答案時只填寫這個整數,填寫多餘的內容將無法得分。

解題思路:

暴力題,但是需要注意的是去重,題目說了不同順序而數字相同的情況只能算一種,比賽的時候真的把這道題想簡單了,以爲只用一個標記數組就可以去重,不知道的是還有可能有這種情況:假設 a + b + c == 2019,然後再假設 d + e + f == 2019,如果這個時候 a + d + f == 2019,這其實可以算是一種新的情況,但是如果只採用一個標記數組的話會認爲 a, d, f 這三個數字都出現過,即漏了這種情況。在這裏我將 a b c 通過 10 進制運算的形式組成一個新的數字,然後放在 mark 標記數組裏面,如果下一次有數字符合 a + b + c ==2019 ,則將他們也組成一個新的數字,然後在已有的 mark 數組裏面找,如果找到了,則證明重合,否則就是新情況,放入 mark 數組中記錄。
上面是之前的想法,把問題想複雜了,感謝評論區小夥伴的指正,我們可以讓 3 個變量(假設爲 a, b, c)從 1 開始枚舉,即暴力,這樣的出來的結果肯定會有重複,重複原因就是 a 可能和 b、c 重合,同樣,b 也可能和 a、c 出現重合,c 也可能和 a、b 重合。即需要把結果除以 6 。
另一種更簡單的想法則是在循環時就控制 a, b 和 c 的起始值,即 a 從 1 開始, b 從 a + 1 開始,c 從 b + 1 開始。這樣 a, b 和 c 就不會相等,同時也不會出現重複,因爲每一次循環得到的 a, b 和 c 和之前出現過的 a, b 和 c 中必定至少有一個數不同,這樣得到的結果就是最終結果。從時間複雜度上將,第二種思路是比第一種思路快的。

代碼:

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

// 判斷某個數字位中是否包含 2 和 4 
bool judge(int n) {
	int t;
	while (n) {
		if (((t = n % 10) == 2) || t == 4) {
			return true;
		}
		n /= 10;
	}
	return false;
}

bool check(int a, int b, int c) {
	// 有數字出現 2 和 4,或者出現重複數字,返回 0 
	if (judge(a) || judge(b) || judge(c) || 
		a == b || a == c || b == c) {
		return false;
	}
	return true;
}

/**
 * 第一種思路:直接枚舉後將結果 / 6
 */
int main() {
	int res = 0;
	for (int i = 1; i < 2018; i++) {
		for (int j = 1; j < 2018; j++) {
			for (int k = 1; k < 2018; k++) {
				if (i + j + k == 2019) {
					res += check(i, j, k);
				}
			}
		}
	}
	cout << (res / 6) << endl;
	return 0;
} 

/**
 * 第二種思路:循環的時候控制變量的起始值:
 */
int main() {
	int res = 0;
	for (int i = 1; i < 2018; i++) {
		for (int j = i + 1; j < 2018; j++) {
			for (int k = j + 1; k < 2018; k++) {
				if (i + j + k == 2019) {
					res += check(i, j, k);
				}
			}
		}
	}
	cout << res << endl;
	return 0;
} 

答案:40785

藍橋杯,ACM算法進階資料大放送

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章