UVa Problem Solution: 701 - The Archaeologist's Dilemma


Let P denotes the prefix, T denotes the # of lost digits. We are searching for N, that the prefix of 2^N is P.
We have an inequlity of
    P*10^T <= 2^N < (P+1)*10^T
thus
    log2(P*10^T) <= log2(2^N) < log2((P+1)*10^T),
which is
    log2(P)+T*log2(10) <= N < log2(P+1)+T*log2(10).
Also, we know that
    P < 10^(T-1),
that is
    T > log10(P)+1.
Then, we can brute force on T and find the minmum N.

Code:
  1. /*************************************************************************
  2.  * Copyright (C) 2008 by liukaipeng                                      *
  3.  * liukaipeng at gmail dot com                                           *
  4.  *************************************************************************/
  5. /* @JUDGE_ID 00000 701 C++ "The Archaeologist's Dilemma" */
  6. #include <algorithm>
  7. #include <cmath>
  8. #include <cstdio>
  9. #include <cstring>
  10. #include <deque>
  11. #include <fstream>
  12. #include <iostream>
  13. #include <list>
  14. #include <map>
  15. #include <queue>
  16. #include <set>
  17. #include <stack>
  18. #include <string>
  19. #include <vector>
  20. using namespace std;
  21. /*
  22.   Let P denotes the prefix, T denotes the # of lost digits. We are searching
  23.   for N, that the prefix of 2^N is P. 
  24.   We have an inequlity of
  25.     P*10^T <= 2^N < (P+1)*10^T
  26.   thus
  27.     log2(P*10^T) <= log2(2^N) < log2((P+1)*10^T),
  28.   which is
  29.     log2(P)+T*log2(10) <= N < log2(P+1)+T*log2(10).
  30.   Also, we know that
  31.     P < 10^(T-1),
  32.   that is
  33.     T > log10(P)+1.
  34.   Then, we can brute force on T and find the minmum N.
  35.  */    
  36. long double minexpof2with(long double prefix)
  37. {
  38.   long double lower = log2l(prefix);
  39.   long double upper = log2l(prefix + 1);
  40.   long double f = log2l(10);
  41.   long double t = ceill(log10l(prefix+0.5)) + 1; // avoid log10l(1) == 0
  42.   for (; ceill(lower+t*f) != floorl(upper+t*f); t += 1) {}
  43.   return ceill(lower+t*f);
  44. }
  45.           
  46. int main(int argc, char *argv[])
  47. {
  48. #ifndef ONLINE_JUDGE
  49.   freopen((string(argv[0]) + ".in").c_str(), "r", stdin);
  50.   freopen((string(argv[0]) + ".out").c_str(), "w", stdout);
  51. #endif
  52.   long double prefix;
  53.   while (cin >> prefix)
  54.     cout << (long long)minexpof2with(prefix) << '/n';
  55.   return 0;
  56. }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章