題意:給定一個數n,問從1到n中,0~9這10個數字分別出現了多少次。比如366這個數,3出現了1次,6出現了2次。
題解:《劍指offer》P174;《編程之美》P132 都給出了統計數字1的O(log(n))的解法。把他們進行改進就得到了這個問題的答案。
下面這個代碼是我改的劍指offer的,也有類似編程之美的:傳送門。
//《劍指offer》P174 #include <bits/stdc++.h> using namespace std; int pow1(int n,int len)//注意算的時候不要用math里的pow 會產生誤差 { int ans=1; while(len--) ans*=n; return ans; } int cal(char *c,int i) { int len=strlen(c); int f=*c-'0',g=*(c+1)-'0'; if(len==1&&(f<i||i==0)) return 0; if(len==1&&f>=i) return 1; int a1=0,a2=0,a3=0; if(i==0||f<i) a1=0; else if(f>i) a1=pow1(10,len-1); else if(f==i) a1=atoi(c+1)+1; a2=f*(len-1)*pow1(10,len-2); if(g==0&&i==0) a2=a2-pow1(10,len-2)+atoi(c+2)+1; a3=cal(c+1,i); return a1+a2+a3; } int solve(int n,int i) { char c[55]; sprintf(c,"%d",n); return cal(c,i); } int main() { int n; while(scanf("%d",&n)!=EOF){ for(int i=0;i<10;i++) printf("%d%c",solve(n,i),i==9?'\n':' '); } return 0; }
官方標程:
#include <bits/stdc++.h> using namespace std; vector<int> solve(int n) { vector<int> res(10, 0); if(!n) return res; if(n % 10 < 9) { res = solve(n - 1); while(n) { res[n % 10]++; n /= 10; } return res; } res = solve(n / 10); for(int i = 0; i < 10; i++) res[i] = res[i] * 10 + n / 10 + (i > 0); return res; } int main() { int n; cin >> n; vector<int> ans = solve(n); for(int i = 0; i < ans.size(); i++) { i == 0 ? cout << ans[i] : cout << " " << ans[i]; } return 0; }