UVa Problem Solution: 10213 - How Many Pieces of Land?


I use this formula to calculate: f(n) = (n,4) + (n,2) + 1. Detailed explanation is available here.

I really need to implement a big integer class. The following code is rather ugly.

Code:
  1. /*************************************************************************
  2.  * Copyright (C) 2008 by liukaipeng                                      *
  3.  * liukaipeng at gmail dot com                                           *
  4.  *************************************************************************/
  5. /* @JUDGE_ID 00000 10213 C++ "How Many Pieces of Land?" */
  6. #include <algorithm>
  7. #include <cstdio>
  8. #include <cstring>
  9. #include <deque>
  10. #include <fstream>
  11. #include <iostream>
  12. #include <list>
  13. #include <map>
  14. #include <queue>
  15. #include <set>
  16. #include <stack>
  17. #include <string>
  18. #include <vector>
  19. using namespace std;
  20. typedef unsigned long long ulonglong;
  21.      
  22. string add(string const& x, string const& y)
  23. {
  24.   int sumlen = max(x.size(), y.size()) + 1;
  25.   string sum(sumlen, '0'), xtmp(sumlen, '0'), ytmp(sumlen, '0');
  26.   int xstart = sumlen - x.size(), ystart = sumlen - y.size();
  27.   copy(x.begin(), x.end(), xtmp.begin() + xstart);
  28.   copy(y.begin(), y.end(), ytmp.begin() + ystart);
  29.   for (int i = sumlen-1, s, carry = 0; i >= 0; --i, carry = s / 10)
  30.     sum[i] = (s = xtmp[i] + ytmp[i] - '0' - '0' + carry) % 10 + '0';
  31.   for (; sum[0] == '0'; sum.erase(0, 1)) {}
  32.   return sum;
  33. }
  34. string muladd(ulonglong x, ulonglong y, ulonglong z)
  35. {
  36.   int const shift = 31;
  37.   ulonglong x1 = x >> shift, x2 = x & ((1LL << shift) - 1);
  38.   ulonglong y1 = y >> shift, y2 = y & ((1LL << shift) - 1);
  39.   ulonglong z1 = z >> shift, z2 = z & ((1LL << shift) - 1);
  40.   ulonglong high = x1*y1, mid = x1*y2 + x2*y1 + z1, low = x2*y2 + z2;
  41.   string tmp;
  42.   for (; high != 0; high /= 10)
  43.     tmp.append(1, high % 10 + '0');
  44.   string highs(tmp.rbegin(), tmp.rend());
  45.   for (tmp.clear(); mid != 0; mid /= 10)
  46.     tmp.append(1, mid % 10 + '0');
  47.   string mids(tmp.rbegin(), tmp.rend());
  48.   for (tmp.clear(); low != 0; low /= 10)
  49.     tmp.append(1, low % 10 + '0');
  50.   string lows(tmp.rbegin(), tmp.rend());
  51.   for (int i = 0; i < shift*2; ++i) 
  52.     highs = add(highs, highs);
  53.   for (int i = 0; i < shift; ++i)
  54.     mids = add(mids, mids);
  55.   string product = add(highs, mids);
  56.   product = add(product, lows);
  57.   return product;
  58. }
  59.           
  60. int main(int argc, char *argv[])
  61. {
  62. #ifndef ONLINE_JUDGE
  63.   freopen((string(argv[0]) + ".in").c_str(), "r", stdin);
  64.   freopen((string(argv[0]) + ".out").c_str(), "w", stdout);
  65. #endif
  66.   /* f(n) = (n,4) + (n,2) + 1 */
  67.   int ncases;
  68.   cin >> ncases;
  69.   while (ncases-- > 0) {
  70.     ulonglong n;
  71.     cin >> n;
  72.     if (n < 4) {
  73.       ulonglong fn = 1;
  74.       for (int i = 1; i < n; ++i)
  75.         fn *= 2;
  76.       cout << fn << '/n';
  77.     } else if (n < 1 << 16) {
  78.       ulonglong fn = n*(n-1)/2*(n-2)/3*(n-3)/4;
  79.       fn += n % 2 == 0 ? n/2*(n-1) : (n-1)/2*n;
  80.       fn += 1;
  81.       cout << fn << '/n';
  82.     } else {
  83.       ulonglong x = n*(n-1)/2, y = (n-2)*(n-3)/2;
  84.       if (x % 2 == 0) x /= 2;
  85.       else y /= 2;
  86.       if (x % 3 == 0) x /= 3;
  87.       else y /= 3;
  88.       ulonglong z = (n % 2 == 0 ? n/2*(n-1) : (n-1)/2*n);
  89.       z += 1;
  90.       string fn = muladd(x, y, z);
  91.       cout << fn << '/n';
  92.     }
  93.   }
  94.   return 0;
  95. }

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