ACM PKU poj 2084 Game of Connections
题目描述:http://poj.org/problem?id=2084
这道题必须要贴一下,我的第一道卡特兰数,顺便测试一下我的大数模板,哈哈,T了一次,后来改成打表就A了,顺便贴上我的JAVA代码;
C++代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #include<iostream> #include<vector> #include<string> //--------------------------------------------------------------------------- using namespace std; class LargeNum { public: vector<int> Num; int operator [](int i)const {return Num[i];} int FindMiddle(int L,int R,LargeNum divd,LargeNum divs); unsigned int size() const{return Num.size();} public: LargeNum(int obj = 0); LargeNum(vector <int> obj):Num(obj){} bool operator < (const LargeNum & obj)const; bool operator > (const LargeNum & obj)const; bool operator == (const LargeNum & obj)const; bool operator != (const LargeNum & obj)const; bool operator >= (const LargeNum & obj)const; bool operator <= (const LargeNum & obj)const; LargeNum operator + (const LargeNum & obj); LargeNum operator += (const LargeNum & obj); LargeNum operator * (const LargeNum & obj); LargeNum operator *= (const LargeNum & obj); LargeNum operator - (const LargeNum & obj); LargeNum operator -= (const LargeNum & obj); LargeNum operator / (const LargeNum & obj); LargeNum operator /= (const LargeNum & obj); LargeNum operator % (const LargeNum & obj); LargeNum operator %= (const LargeNum & obj); friend ostream & operator<<(ostream & out,const LargeNum& A); friend istream & operator>>(istream & in , LargeNum& A); }; int LargeNum::FindMiddle(int L,int R,LargeNum divd,LargeNum divs){ int Middle =(L + R) /2; LargeNum tmp = divs*LargeNum(Middle); if(tmp <= divd && divd - tmp < divs) return Middle; if(tmp > divd) return FindMiddle(Middle- 1,R,divd,divs); else return FindMiddle(L,Middle + 1,divd,divs); } LargeNum:: LargeNum(int obj ){ while(obj > 0){ Num.push_back(obj %10000); obj/= 10000; } if(Num.size() == 0) Num.push_back(0); } LargeNum LargeNum::operator + (const LargeNum & obj){ vector<int> tpRt; vector<int> ttp = Num; for(unsigned int i = 0; i < obj.size(); i++) tpRt.push_back(obj[i]); while (tpRt.size() < Num.size()) tpRt.push_back(0); while (ttp.size() < tpRt.size()) ttp.push_back(0); int Qu = 0; for (unsigned int k = 0; k < tpRt.size(); k++){ tpRt[k]= ttp[k] + tpRt[k] + Qu; Qu = tpRt[k] / 10000; tpRt[k] %= 10000; } while (Qu > 0){ tpRt.push_back(Qu%10000); Qu = Qu / 10000; } return LargeNum(tpRt); } LargeNum LargeNum::operator * (const LargeNum & obj){ vector<int> tpRt; LargeNum Result(tpRt); int Carry = 0; for(unsigned int i = 0; i < obj.size(); i++){ while(tpRt.size() < i) tpRt.push_back(0); for(unsigned int j = 0; j < Num.size(); j++) { Carry = obj[i]*Num[j] + Carry; tpRt.push_back(Carry % 10000); Carry /= 10000; } while(Carry != 0){ tpRt.push_back(Carry%10000); Carry /=10000;} Result = Result + LargeNum(tpRt); tpRt.clear(); } return Result; } LargeNum LargeNum::operator - (const LargeNum & obj){ vector<int> tmp = Num; for(unsigned int i = 0; i < obj.size(); i ++){ if(tmp[i] - obj[i] < 0){ tmp[i] += 10000; tmp[i+1]-= 1; int k = i+1; while(tmp[k] < 0){ tmp[k] += 10000; tmp[++k] -= 1; } } tmp[i]-= obj[i]; } for(int i = tmp.size() - 1; i > 0; i--) if(tmp[i] == 0) tmp.pop_back(); else break; return LargeNum(tmp); } LargeNum LargeNum::operator / (const LargeNum & obj){ if(obj > *this) return LargeNum(0); else if(obj == *this) return LargeNum(1); else { vector<int> tpRt; vector<int> Result; LargeNum temp = *this,Rt(0); while(obj < temp){ for(unsigned int i = 0; i < obj.size(); i++) tpRt.push_back(obj[i]); int step = 0; while (LargeNum(tpRt) < temp ){ tpRt.insert(tpRt.begin(),0); step++; } tpRt.erase(tpRt.begin()); int k = FindMiddle(10000,1,temp,LargeNum(tpRt)); temp = temp - LargeNum(k)*LargeNum(tpRt); while(step-- > 1) Result.push_back(0); Result.push_back(k); Rt += LargeNum(Result); Result.clear(); tpRt.clear(); } return Rt; } } LargeNum LargeNum::operator % (const LargeNum & obj){ LargeNum temp = *this; return temp - (temp/obj)*obj; } LargeNum LargeNum::operator += (const LargeNum & obj){ return *this = *this + obj; } LargeNum LargeNum::operator *= (const LargeNum & obj){ return *this = *this * obj; } LargeNum LargeNum::operator -= (const LargeNum & obj){ return *this = *this - obj; } LargeNum LargeNum::operator /= (const LargeNum & obj){ return *this = *this / obj; } LargeNum LargeNum::operator %= (const LargeNum & obj){ return *this = *this % obj; } bool LargeNum::operator < (const LargeNum & obj)const { if(Num.size() < obj.size()) return true; else if(Num.size() == obj.size()){ for(int i = Num.size() - 1; i >= 0; i--) if(this->Num[i] < obj[i]) return true; else if(this->Num[i] > obj[i]) return false; } return false; } bool LargeNum::operator == (const LargeNum & obj)const { if(obj.size() == Num.size()){ for(unsigned int i = 0; i < Num.size(); i++) if(obj[i] != Num[i]) return false; return true; } return false; } bool LargeNum::operator > (const LargeNum & obj)const { return obj < *this; } bool LargeNum::operator != (const LargeNum & obj)const{ return !(*this == obj); } bool LargeNum::operator >= (const LargeNum & obj)const{ return (*this > obj || *this == obj); } bool LargeNum::operator <= (const LargeNum & obj)const{ return (*this < obj || *this == obj); } ostream & operator<<(ostream & out,const LargeNum& A) { out << A[A.size()- 1]; for(int i = A.size()- 2; i >= 0; i--) { if(A[i] < 1000) out << 0; if(A[i] < 100) out << 0; if(A[i] < 10) out << 0; out << A[i]; } return out; } istream & operator>>(istream & in , LargeNum& A){ string str; in >> str; A.Num.clear(); int tpval = 0,k = str.size() - 4; while(k >= 0){ for(int i = 0; i < 4; i++) tpval = tpval*10 + str[k+i] - '0'; k -= 4; A.Num.push_back(tpval); tpval = 0; } k = str.size()% 4; for(int i = 0; i < k; i++) tpval = tpval *10 + str[i] - '0'; if(tpval != 0) A.Num.push_back(tpval); return in; } LargeNum num[110]; LargeNum h(int A) { if(A==0) return num[0]; else return num[A]=h(A-1)*(A*4-2)/(A+1); } int main() { int A; num[0]=1; h(105); while(scanf("%d",&A)&&A!=-1) { cout<<num[A]<<endl; } return 0; }
java代码:
import java.math.*; import java.io.*; import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(new BufferedInputStream(System.in)); BigInteger[] a = new BigInteger[200]; a[1] = new BigInteger("1"); a[2] = new BigInteger("2"); for (int i=3; i<=103; i++) { int t1 = 4*i-2; int t2 = i+1; a[i] = a[i-1].multiply(new BigInteger(""+t1)).divide(new BigInteger(""+t2)); } while (true) { int n = in.nextInt(); if (n==-1) break; System.out.println(a[n]); } } }