http://acm.hdu.edu.cn/showproblem.php?pid=3215題目大意是計算2^0到2^n中每個數(shù)的最左邊一位,然后記錄1-9每個數(shù)字出現(xiàn)的次數(shù)并依次打印出來;
考慮到n的范圍 [0,10000], 不可能去計算 2^n
hdu 1060 Leftmost Digit
http://acm.hdu.edu.cn/showproblem.php?pid=1060 與此題一樣
/**
先看一個例子:
31415926 最左面那位數(shù)是3,如何得來?
取對數(shù): lg(3.1415926 * 10^7) = lg(3.1415926) + 7
也就是說,一個整數(shù)取對數(shù)以后變?yōu)?部分,不妨設(shè)小數(shù)部分為A (0 <= A < 1),整數(shù)部分為B
所以,一個整數(shù)可以寫成 10^A * 10^B
至于 10^B 是大家熟悉的 10000……
而 10^A 是什么樣子的呢? 肯定是小于10的小數(shù) (為什么呢,如果大于10了,B的值則加1)
那么 A 的整數(shù)部分就是我們要求的數(shù)
大致思路就是:對一個數(shù)x求對數(shù),取出小數(shù)部分A,則10^A的整數(shù)部分就是x的最左面的那位數(shù)
進入本題:
x = 2^n
lg(x) = n * lg(2)
A = lg(x) - lg(x)的整數(shù)部分
10^A = ……
其實這道題卡的事精度問題,整數(shù)與小數(shù)來回轉(zhuǎn)化肯定有精度損失 這里的A要加上1.0e-6
*/
#include <stdio.h>
#include <math.h>
#define eps (1.0e-6)
int f[10010][10];
int main()
{
int i, j, y;
double A, x, s=log10(2);
f[0][1]=1;
for (i=1; i<=10000; i++) {
for(j=1; j<10; j++)
f[i][j] = f[i-1][j];
x = i * s;
A = x - (int)x;
y = (int) (pow(10, A)+eps);
f[i][y]++;
}
while (scanf("%d",&y),y+1) {
printf("%d", f[y][1]);
for(i=2; i<10; i++)
printf(" %d",f[y][i]);
printf("\n");
}
return 0;
}
posted on 2009-11-27 14:25
西風(fēng)蕭瑟 閱讀(1224)
評論(1) 編輯 收藏 引用 所屬分類:
數(shù)學(xué)