1049. Counting Ones (30)
題目如下:
The task is simple: given any positive integer N, you are supposed to count the total number of 1's in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1's in 1, 10, 11, and 12.
Input Specification:
Each input file contains one test case which gives the positive N (<=230).
Output Specification:
For each test case, print the number of 1's in one line.
Sample Input: 12 Sample Output: 5對于此類問題,應當從找一般化的規律為主,而不應當試圖推導排序組合的數學表達式。
這道題目的難點在于每一位都有出現1的可能,例如100,010,001,110等,如果按照排序組合考慮,因為要計數1的個數,因此對于1的個數不同,要分別對待,這將會是很棘手的問題。
如果換個思路,從每一位入手,研究每一位的規律,則會使得問題簡單得多,這種研究方法是科學的,因為每一位都考慮了自己的1,那么合起來對于多個1的問題就自然考慮進來了,例如N=12時,我們分別考慮下面的情況:
個位出現1的有1,11,十位出現1的有10,11,12,我們看到,對于11這種多個1的情況,正好計算了兩次,對于多位也是這個道理。
下面我們從一個5位數入手,研究百位不同時,百位為1的所有情況的計算:
我們以12045、12145、12245為例。
12045:
百位為0,那么高位不變低位部分無法產生類似1XX的數字,因此考慮高位,注意到只要比當前值小就可以,因此可選擇:00100-00199,01100-01199 ... 11100-11199 一共12*100=1200,觀察到等于比當前高位的數字*100。
也就是:高位數字*100,注意到這個100和當前考慮的位有關,百位為100,從低位為第1位開始計算第x位為10的x次方,也就是說對不同的位這個100應該換成相應的值。
12145:
百位為1,那么高位不變,低位從100-145都可以,共45+1=46個,高位仍然可以產生百位為0時的變化,共1200+46+1246種
也就是:高位數字*100 + 低位數字+1
12245:
對于百位大于1的情況,我們只需要考慮高位即可列全所有,從00100-00199到12100-12199,共13*100=1300
也就是:(高位數字 + 1)*100
解決了這個問題,下面要解決的是取出高位數、當前位、低位數的問題,我們以6位數abcdef取出百位為例:
對于abcdef,設因數factor=100,即要取出百位d
按照常規方法,百位 = abcdef / factor % 10 = abcd % 10 = d
高位數字 = abcdef / factor / 10 = abc
低位數字 = abcdef - abcd00 = ef
而abcd00 = (abcdef / factor) * factor = abcd00
所以低位數字 = abcdef - ( abcdef / factor ) * factor
這時候,factor就是前面我們要找的從低位開始算的10的x次方,因此編寫代碼變得簡單,只需要從低位開始,也就是factor從1開始,每次乘以10,直到超出當前值,此時N/factor=0,停止運算。
代碼如下:
#include <iostream> #include <stdio.h>using namespace std;int compute(int N){int factor = 1;int low = 0;int high = 0;int now = 0;int cnt = 0;while(N / factor != 0){now = (N / factor) % 10;high = N / factor / 10;low = N - (N / factor) * factor;switch(now){case 0:cnt += high * factor;break;case 1:cnt += high * factor + low + 1;break;default:cnt += (high + 1) * factor;}factor *= 10;}return cnt;}int main() {int N;while(scanf("%d",&N) != EOF){cout << compute(N) << endl;}return 0; }
轉載于:https://www.cnblogs.com/aiwz/p/6154130.html
總結
以上是生活随笔為你收集整理的1049. Counting Ones (30)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#去掉字符串中的汉字
- 下一篇: Linux网络基础设施配置