UVa Problem Solution: 10183 - How many fibs?


The close form of fibs does not help in the problem. The input range is too large that the precision of long double won't be sufficient to handle it correctly. Just generate all the fibs up to 100 digits and use string compare to find the bounds.

Code:
  1. /*************************************************************************
  2.  * Copyright (C) 2008 by liukaipeng                                      *
  3.  * liukaipeng at gmail dot com                                           *
  4.  *************************************************************************/
  5. /* @JUDGE_ID 00000 10183 C++ "How many fibs?" */
  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. struct bignum
  22. {
  23.   bignum(int v = 0) : start(max_digits)
  24.   {
  25.     bzero(digits, max_digits);
  26.     assign(v);
  27.   }
  28.   bignum(char const *v) : start(max_digits)
  29.   {
  30.     bzero(digits, max_digits);
  31.     assign(v);
  32.   }
  33.   void assign(int v)
  34.   {
  35.     start = max_digits;
  36.     for (; v != 0; v /= 10) digits[--start] = v % 10; 
  37.   }
  38.   void assign(char const *v)
  39.   {
  40.     start = max_digits - strlen(v);
  41.     for (int i = start; i < max_digits; ++i)
  42.       digits[i] = *v++ - '0';
  43.     remove_leading_zero();
  44.   }
  45.   void convert(int& v) const
  46.   {
  47.     v = 0;
  48.     for (int i = start; i < max_digits; ++i, v *= 10) v += digits[i]; 
  49.   }
  50.   void convert(char *v) const
  51.   {
  52.     for (int i = start; i < max_digits; ++i)
  53.       *v++ = digits[i] + '0';
  54.     *v = '/0';
  55.   }
  56.   bignum& operator+=(bignum const& other)
  57.   {
  58.     start = min(start, other.start) - 1;
  59.     for (int i = max_digits - 1, carry = 0; i >= start; --i) {
  60.       int s = digits[i] + other.digits[i] + carry;
  61.       digits[i] = s % 10;
  62.       carry = s / 10;
  63.     }
  64.     remove_leading_zero();
  65.     return *this;
  66.   }
  67.   bignum operator+(bignum const& other) const
  68.   {
  69.     bignum tmp(*this);
  70.     tmp += other;
  71.     return tmp;
  72.   }
  73.   bool operator<(bignum const& other) const
  74.   {
  75.     if (start > other.start) return true;
  76.     else if (start < other.start) return false
  77.     return memcmp(digits + start, other.digits + start, max_digits - start) < 0;
  78.   }
  79.   static int const max_digits = 500;
  80.   char digits[max_digits];
  81.   int start;
  82. private:
  83.   void remove_leading_zero()
  84.   {
  85.     for (; digits[start] == 0 && start < max_digits; ++start) {}
  86.   } 
  87. };
  88.     
  89. inline istream& operator>>(istream& is, bignum& n)
  90. {
  91.   char buf[bignum::max_digits+1];
  92.   is >> buf;
  93.   n.assign(buf);
  94.   return is;
  95. }
  96. inline ostream& operator<<(ostream& os, bignum const& n)
  97. {
  98.   char buf[bignum::max_digits+1];
  99.   n.convert(buf);
  100.   os << buf;
  101.   return os;
  102. }
  103. /*
  104.  * generate the fibs
  105.  */
  106. void gen_fibs(bignum *fibs, int nfibs)
  107. {
  108.   fibs[0] = 1;
  109.   fibs[1] = 2;
  110.   for (int i = 2; i < nfibs; ++i)
  111.     fibs[i] = fibs[i-1] + fibs[i-2];
  112. }
  113.         
  114. int main(int argc, char *argv[])
  115. {
  116. #ifndef ONLINE_JUDGE
  117.   freopen((string(argv[0]) + ".in").c_str(), "r", stdin);
  118.   freopen((string(argv[0]) + ".out").c_str(), "w", stdout);
  119. #endif
  120.   int const nfibs = 500;
  121.   bignum fibs[nfibs];
  122.   gen_fibs(fibs, nfibs);
  123.   for (string s1, s2; cin >> s1 >> s2 && !(s1 == "0" && s2 == "0"); ) {
  124.     bignum a(s1.c_str()), b(s2.c_str());
  125.     int count;
  126.     if (b < a) {
  127.       count = 0;
  128.     } else {
  129.       bignum *first = lower_bound(fibs, fibs + nfibs, a);
  130.       bignum *last = upper_bound(fibs, fibs + nfibs, b);
  131.       count = last - first;
  132.     }
  133.     cout << count << '/n';
  134.   }
  135.   return 0;
  136. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值