Posted on 2010-08-11 16:49
Onway 閱讀(1781)
評論(2) 編輯 收藏 引用 所屬分類:
傷不起的ACM
pku 2109 一句話就能AC得題目?
這個題目的是求一個大整數p(10^101)開n(1<=n<=200)次方的結果k,即k^n=p或者,n=log k (p).
題目說保證p和n都是整數,并且求到得結果k一定是一個整數。但discuss里有說,有些測試數據是不存在整數k的。
這個題目的本意應該是高精度加二分吧,但我沒寫。
在discuss看到,有些是直接用double和pow()函數的,一句話AC了以后,有很大的“罪惡感”。
本人小菜,連double和pow()都不會用,用了也是一頭霧水,覺得這種方法能通過,完全是因為測試數據太弱。
(在VC++ 6.0調試)
一句話能AC的C代碼是這樣的:
#include <stdio.h>
#include <math.h>
void main()
{
double n,p;
while(scanf("%lf%lf",&n,&p)!=EOF)
printf("%.0f\n",pow(p,1/n));
}
首先用double接受一個10^101次方的數,確實可以,因為double的范圍是-1.7^308~1.7^308,但精度只有16或17位(四舍五入位)。
然后設p是一個大于17位的整數,那么四舍五入后可能得到的兩個值p1和p2,不妨記p1>p,p2<p。
就算測試數據都是合法的,就是說能保證k是一個整數,即有k=p^(1/n)。那么可以保證的是p1^(1/n)>k而p2^(1/n)<k的。
那么問題就來了,p1^(1/n)的上界怎么確定,p2^(1/n)的下界又怎么確定呢?
用double和pow()函數至少要能確保k+1>p1^(1/n)>k和k-1<p2^(1/n)<k吧?因為只有這樣,對結果pow(p,1/n)四舍五入才能得到結果k。
但如何能確保對p用double存儲的時候得到的估計值p1和p2的精確度在
p1-p<(k+1)^n-k^n和p-p2>k^n-(k-1)^n呢?
本人的智商只能到這里,還望各路神牛不吝賜教。