暴力求解,1-2008080808算完估计天都黑了还算不出。从数学思想中,寻找规律是比较常规。用DP思想也挺不错的,按位数长度不同来逐渐填表,不过没去实现。看各位大虾回复中,发现2种挺不错的做法,摘录学习之:
(1) 观察10,100,1000,10000得:f(n)=10^(n-1)+f(n-1)*10-f(n-1)=10^(n-1)+f(n-1)*9
(1) f(n):10^n中含7的数字的个数
(2) f(n-1):10^(n-1)中含7的数字的个数,因为在n位数中n-1位数可以从零到九,所以乘10
(3) 10^(n-1)代表第n-1位为7的数字的个数
(4) 因为(2) 和(3)中有重复的数,其个数为f(n-),所以减去f(n-1)
- unsigned long getNumber(n)
- {
- unsigned count=0;
- if(n==1)
- count=1;
- else
- {
- count=f(n-1)*9+10^(n-1);
- }
- return count;
- }
- g(2008080808)=2*f(10)+8*f(7)+8*f(7)+8*f(3)+f(1)
(2)
- #include<algorithm>
- int main(void)
- {
- int n, nn=1; //统计7
- while (scanf("%d", &n)!=EOF)
- {
- int nlist[16], nb, s=0, t=n, p=0;
- for (nb=0; t>0; ++nb)
- {
- nlist[nb] = t%10;
- if (nlist[nb] > nn)
- {
- --nlist[nb];
- }
- else if (nlist[nb] == nn)
- {
- --nlist[nb];
- for (; p<nb; ++p)
- {
- nlist[p] = 8;//因为高位为7, 该数定是含7的数。去之。
- }
- }
- t /= 10;
- }
- for (--nb; nb>=0; --nb)
- {
- s = s*9 + nlist[nb];
- }
- printf("%d/n", n - s);
- }
- return 0;
- }
第二种是9进制的思想。 初始 - 不含7的数 = 含7的数。