【3006】统计数字
統計數字
Time Limit: 3 second
Memory Limit: 2 MB
【問題描述】
??? 一本書的頁數為N,頁碼從1開始編起,請你求出全部頁碼中,用了多少個0、1、2、3、4、5、6、7、8、9。其中每個頁碼不含多余的0,如N=123時,第5頁不是005,只是5,第12頁不是012,只是12。【輸入】
??? 輸入文件僅一行,一個正整數N(N≤109),表示總的頁碼數。
【輸出】
??? 輸出文件十行,第K行為數字k-1的個數,即第一行為數字0的個數,第二行為數字1的個數,第三行為數字2的個數,以此類推。
【輸入樣例】
11【輸出樣例】
1 4 1 1 1 1 1 1 1 1 ?【題解】
這題很惡心,沒錯 又是惡心這個詞,以后只可能會越來越多地出現這個詞。不會減少。。。
我是看著題解寫的程序。
首先,從000-999 我們不要刪掉多余的0,那么我們會有1000個3位數,然后一共有3000個數字出現過,可以想想0-9,每個數字都只出現一次,00-99,也可以知道0-9每個數字都出現相同的次數。推廣一下,000-999每個數字出現的次數也是一樣的。
然后3000個數字,0-9有10個,則每個數字都有用到300次。
先別問我0的事!
然后我們舉個例子。
6147
我們先看6,6之前有0-5,后3位,都從000-999變化,剛才我們算出來了,每個數字都會用到300次,0-5有6位,所以a[0..9]+=6*300;
然后是0-5這6個數字作為第一位,每個都出現過1000次,即0XXX 1XXX 2XXX...其中XXX ∈ [000,999];
最后是6,6我們要單獨處理,要加上148,即6XXX,XXX∈[000..148];
然后處理1,4,7就好。
(這里你用while已經能寫出來了,只要按照6的規律就可以)
?
接下來是0的問題了。
①
先從只有一位數的情況開始。
比如6;
我們先會看看6后面有沒有數字,沒有。
然后看看6前面有沒有數字,有。要加上幾呢? 假設l是數字的長度,我們肯定會這樣做的
t = 1
for (int i = 1; i<=l-1;i++)
? t = t *10;
這里如果是上面說的6174,l=4,則t=1000;
但是這里我們是以6為例,所以t = 1;
然后for (int i = 0;i <=5;i++)
? a[i]+=t;
這里已經多出來一個0了。
剩下步驟省略。。
対,如果一位數字會多出1個0;
②
兩位數。
比如12
我們先會看1后面有沒有數字,有。
那就用下我們上面的公式。
0-9有10個一位數字。。。。然后每個數字被用一次。
則a[0..9]+=1;
//這里出現的0是多出的。
然后是0 被用了 10 次 0-9,
//這里的0也是多出來的。即00 01 02 03...09;
這里出現了11個多余的0
剩下步驟省略,因為沒有出現多余的0.
③
111
④
1111
即多出的0是數字的位數。
【代碼】
#include <cstdio> #include <iostream> #include <string>using namespace std;string s1; unsigned int n; int a[10];void input_data() {cin >> s1; }void get_ans() {int l = s1.size(); //先獲取數據的長度for (int i = 0;i <= 9;i++) //每個數字使用的數目初始化a[i] = 0;int t = 0;for (int i = 1;i <= l;i++) //先減去多余的0,即l(字母L)個1(數字1)t = t*10 + 1;a[0] -= t; //減去多余的0while (l > 0) //如果還能繼續減少長度 基本上寫出第一層第二層就不會有問題了。{int m = s1[0] - '0'; //先取出頭數字t = 1;for (int i = 1;i <= l-1;i++) //這里是6174中 6時的1000t = t * 10;int tt = (t * (l-1))/10; //000 - 999 中每個數字被使用的次數 while進行一次就變成00-99for (int i = 1;i <= m;i++) //0XXX 1XXX 2XXX 。。。。mXXX 中的 XXXfor (int j = 0;j <= 9;j++)a[j] += tt;for (int i = 0;i <= m-1;i++) //0XXX 1XXX 2XXX ... mXXX中的 1..ma[i] += t;s1 = s1.erase(0,1); //這是從int ttt =0;l = s1.size();for (int i = 0;i <l;i++)ttt = ttt*10 + s1[i] - '0';ttt++;a[m] += ttt; //這是統計6147 中的148.}}void output_ans() {for (int i = 0 ;i <= 9;i++)printf("%d\n",a[i]); }int main() {input_data();get_ans();output_ans();return 0; }?
轉載于:https://www.cnblogs.com/AWCXV/p/7632451.html
總結
以上是生活随笔為你收集整理的【3006】统计数字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【codeforces 711B】Chr
- 下一篇: 卷积0.1