“至少出現一次7”的數

(本來是列爲轉載的,但是原文算法那裏有不可原諒的錯誤,憤慨之下,收歸己有)

給定一個正整數n,寫一個算法計算從1到n之間有多少“至少出現一次7”的數。例如n=20,那麼有兩個出現7的數:7,17。

算法

去掉個位的數字有N/10個,這也是個位爲7的數的個數,包含出現多於一個7的情況,以下類推
再去掉十位的數字有N/100個,乘以9是十位爲7的數的個數(個位不能再取7,所以乘9)
再去掉百位的數字有N/1000個,乘以81是百位爲7的數的個數(個位或十位都不能再取7,所以乘9的平方)
依次類推。。。對於個位大於等於7的數字,最後的結果還要+1

例如2000內有7的個數=200+20*9+2*81=542, 2000/10 = 200 是個位出現7的數的個數,2000/200×9是十位出現7的情況,2000/1000×9×9是百位出現7的情況,個位小於7,不需要額外加1。

進一步解釋:以2000作爲例子,考慮個位爲7的情況,從07,17,27一直到1997,個位爲7的情況出現了200次(0到199);  考慮十位爲7的情況,07x,17x,27x一直到197x,其中x代表除了7外的其他數字,所以十位爲7的情況爲20次(0到19)乘以9(個位的情況), 由於排除了個位是7的情況,所以不會跟第一種情況算重; 考慮百位爲7的情況,07xx,17xx,所以百位爲7的情況事2乘以9的平方。

爲什麼個位數大於等於7的話還要額外+1?譬如2018,因爲2017事實上沒有算入之前的幾種情況,只算了(0到200).

這麼一分析的話,代碼就很簡單了:

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

int get7num(int n) {
	int p = 0;
	int num = 0;
	int bonus = (n%10 >= 7);
	while(n != 0) {
		num += (n/10)*pow(9,p);
		p++;
		n /= 10;
	}
	return num + bonus;
}

int main() {
	cout << get7num(2007) << endl;
	return 0;
}




 


發佈了42 篇原創文章 · 獲贊 6 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章