您的位置:首页 > 其它

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

2008-11-26 23:36 447 查看
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:
/*************************************************************************
* Copyright (C) 2008 by liukaipeng *
* liukaipeng at gmail dot com *
*************************************************************************/

/* @JUDGE_ID 00000 10213 C++ "How Many Pieces of Land?" */

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef unsigned long long ulonglong;

string add(string const& x, string const& y)
{
int sumlen = max(x.size(), y.size()) + 1;
string sum(sumlen, '0'), xtmp(sumlen, '0'), ytmp(sumlen, '0');
int xstart = sumlen - x.size(), ystart = sumlen - y.size();
copy(x.begin(), x.end(), xtmp.begin() + xstart);
copy(y.begin(), y.end(), ytmp.begin() + ystart);
for (int i = sumlen-1, s, carry = 0; i >= 0; --i, carry = s / 10)
sum[i] = (s = xtmp[i] + ytmp[i] - '0' - '0' + carry) % 10 + '0';
for (; sum[0] == '0'; sum.erase(0, 1)) {}
return sum;
}

string muladd(ulonglong x, ulonglong y, ulonglong z)
{
int const shift = 31;
ulonglong x1 = x >> shift, x2 = x & ((1LL << shift) - 1);
ulonglong y1 = y >> shift, y2 = y & ((1LL << shift) - 1);
ulonglong z1 = z >> shift, z2 = z & ((1LL << shift) - 1);
ulonglong high = x1*y1, mid = x1*y2 + x2*y1 + z1, low = x2*y2 + z2;
string tmp;
for (; high != 0; high /= 10)
tmp.append(1, high % 10 + '0');
string highs(tmp.rbegin(), tmp.rend());
for (tmp.clear(); mid != 0; mid /= 10)
tmp.append(1, mid % 10 + '0');
string mids(tmp.rbegin(), tmp.rend());
for (tmp.clear(); low != 0; low /= 10)
tmp.append(1, low % 10 + '0');
string lows(tmp.rbegin(), tmp.rend());

for (int i = 0; i < shift*2; ++i)
highs = add(highs, highs);
for (int i = 0; i < shift; ++i)
mids = add(mids, mids);
string product = add(highs, mids);
product = add(product, lows);
return product;
}

int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
freopen((string(argv[0]) + ".in").c_str(), "r", stdin);
freopen((string(argv[0]) + ".out").c_str(), "w", stdout);
#endif

/* f(n) = (n,4) + (n,2) + 1 */
int ncases;
cin >> ncases;
while (ncases-- > 0) {
ulonglong n;
cin >> n;
if (n < 4) {
ulonglong fn = 1;
for (int i = 1; i < n; ++i)
fn *= 2;
cout << fn << '/n';
} else if (n < 1 << 16) {
ulonglong fn = n*(n-1)/2*(n-2)/3*(n-3)/4;
fn += n % 2 == 0 ? n/2*(n-1) : (n-1)/2*n;
fn += 1;
cout << fn << '/n';
} else {
ulonglong x = n*(n-1)/2, y = (n-2)*(n-3)/2;
if (x % 2 == 0) x /= 2;
else y /= 2;
if (x % 3 == 0) x /= 3;
else y /= 3;
ulonglong z = (n % 2 == 0 ? n/2*(n-1) : (n-1)/2*n);
z += 1;
string fn = muladd(x, y, z);
cout << fn << '/n';
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: