1. 程式人生 > >HDU 1134 Game of Connections(卡特蘭數)

HDU 1134 Game of Connections(卡特蘭數)

cut res ras sam eof cpp ont des tel

題目代號:HDU 1134

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1134

Game of Connections

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4668 Accepted Submission(s): 2729

Problem Description This is a small but ancient game. You are supposed to write down the numbers 1, 2, 3, ... , 2n - 1, 2n consecutively in clockwise order on the ground to form a circle, and then, to draw some straight line segments to connect them into number pairs. Every number must be connected to exactly one another. And, no two segments are allowed to intersect.

It‘s still a simple game, isn‘t it? But after you‘ve written down the 2n numbers, can you tell me in how many different ways can you connect the numbers into pairs? Life is harder, right? Input Each line of the input file will be a single positive number n, except the last line, which is a number -1. You may assume that 1 <= n <= 100. Output For each n, print in a single line the number of ways to connect the 2n numbers into pairs. Sample Input 2 3 -1 Sample Output 2 5 題目大意:給出一個值n(n<=100),1,2,3,···2n圍成一個圈,問有多少種方式讓每個數字成對連接的同時不相交。因為數據非常大,所以我選擇先用大數模板算出卡特蘭數的前一百個數據之後打表。 打表代碼:
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <iostream>
# include <fstream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <math.h>
# include <algorithm>
using namespace std;
# define pi acos(-1.0)
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define For(i,n,a) for(int i=n; i>=a; --i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define Fo(i,n,a) for(int i=n; i>a ;--i)
typedef long long LL;
typedef unsigned long long ULL;

string num[105]={"1","1"};

//string比較函數:相等返回0,str1>str2返回1,str1<str2返回-1.
int Compare(string str1,string str2)
{
    if(str1.length() > str2.length()) return 1;
    else if(str1.length() < str2.length()) return -1;
    else return str1.compare(str2);
}

string Big_Plus(string str1,string str2)
{
    string ans;
    int len1=str1.length();
    int len2=str2.length();
    //將長度較小的前面補0,使兩個string長度相同
    if(len1<len2){
        for(int i=1;i<=len2-len1;i++){
            str1="0"+str1;
        }
    }else {
        for(int i=1;i<=len1-len2;i++){
            str2="0"+str2;
        }
    }
    int len=max(len1,len2);
    int carry=0;
    for(int i=len-1;i>=0;i--){
        int tmp=str1[i]-‘0‘+str2[i]-‘0‘+carry;
        carry=tmp/10;
        tmp%=10;
        ans=char(tmp+‘0‘)+ans;
    }
    if(carry) ans=char(carry+‘0‘)+ans;
    return ans;
}

//支持大數減小數
string Big_Sub(string str1,string str2)
{
    string ans;
    int carry=0;
    int difference=str1.length()-str2.length();//長度差
    for(int i=str2.length()-1;i>=0;i--){
        if(str1[difference+i]<str2[i]+carry){
            ans=char(str1[difference+i]+10-str2[i]-carry+‘0‘)+ans;
            carry=1;
        }else {
            ans=char(str1[difference+i]-str2[i]-carry+‘0‘)+ans;
            carry=0;
        }
    }
    for(int i=difference-1;i>=0;i--){
        if(str1[i]-carry>=‘0‘){
            ans=char(str1[i]-carry)+ans;
            carry=0;
        }else {
            ans=char(str1[i]-carry+10)+ans;
            carry=1;
        }
    }
    //去除前導0
    ans.erase(0,ans.find_first_not_of(‘0‘));
    if(ans.empty()) ans="0";
    return ans;
}

string Big_Mul(string str1,string str2)
{
    string ans;
    int len1=str1.length();
    int len2=str2.length();
    for(int i=len2-1;i>=0;i--){
        string tmpstr="";
        int data=str2[i]-‘0‘;
        int carry=0;
        if(data!=0){
            for(int j=1;j<=len2-1-i;j++){
                tmpstr+="0";
            }
            for(int j=len1-1;j>=0;j--){
                int t=data*(str1[j]-‘0‘)+carry;
                carry=t/10;
                t%=10;
                tmpstr=char(t+‘0‘)+tmpstr;
            }
            if(carry!=0) tmpstr=char(carry+‘0‘)+tmpstr;
        }
        ans=Big_Plus(ans,tmpstr);
    }
    ans.erase(0,ans.find_first_not_of(‘0‘));
    if(ans.empty()) ans="0";
    return ans;
}

//正數相除,商為quotient,余數為residue

void Big_Div(string str1,string str2,string& quotient,string& residue)
{
    quotient=residue="";//商和余數清空
    if(str2=="0"){//;判斷除數是否為0
        quotient=residue="ERROR";
        return;
    }
    if(str1=="0"){//判斷被除數是否為0
        quotient=residue="0";
        return;
    }
    int res=Compare(str1,str2);
    if(res<0){//被除數小於除數
        quotient="0";
        residue=str1;
        return;
    }else if(res==0){
        quotient="1";
        residue="0";
        return ;
    }else {
        int len1=str1.length();
        int len2=str2.length();
        string tmpstr;
        tmpstr.append(str1,0,len2-1);//將str1的前len2位賦給tmpstr
        for(int i=len2-1;i<len1;i++){
            tmpstr=tmpstr+str1[i];//被除數新補充一位
            tmpstr.erase(0,tmpstr.find_first_not_of(‘0‘));//去除前導0
            if(tmpstr.empty()) tmpstr="0";
            for(char ch=‘9‘;ch>=‘0‘;ch--){//試商
                string tmp,ans;
                tmp=tmp+ch;
                ans=Big_Mul(str2,tmp);//計算乘積
                if(Compare(ans,tmpstr)<=0){//試商成功
                    quotient=quotient+ch;
                    tmpstr=Big_Sub(tmpstr,ans);//減掉乘積
                    break;
                }
            }
        }
        residue=tmpstr;
    }
    quotient.erase(0,quotient.find_first_not_of(‘0‘));
    if(quotient.empty()) quotient="0";
}

int main()
{
    int n;
    for(int i=0;i<=100;i++)
    {
        if(i>1)for(int j=0;j<i;j++)
        {
            num[i]=Big_Plus(Big_Mul(num[j],num[i-j-1]),num[i]);
        }
        cout<<"\""<<num[i]<<"\","<<endl;
    }
    return 0;
}

  

打表完成後的代碼很容易:

# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <iostream>
# include <fstream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <math.h>
# include <algorithm>
using namespace std;
# define pi acos(-1.0)
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define For(i,n,a) for(int i=n; i>=a; --i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define Fo(i,n,a) for(int i=n; i>a ;--i)
typedef long long LL;
typedef unsigned long long ULL;

string num[105]= {"1",
                  "1",
                  "2",
                  "5",
                  "14",
                  "42",
                  "132",
                  "429",
                  "1430",
                  "4862",
                  "16796",
                  "58786",
                  "208012",
                  "742900",
                  "2674440",
                  "9694845",
                  "35357670",
                  "129644790",
                  "477638700",
                  "1767263190",
                  "6564120420",
                  "24466267020",
                  "91482563640",
                  "343059613650",
                  "1289904147324",
                  "4861946401452",
                  "18367353072152",
                  "69533550916004",
                  "263747951750360",
                  "1002242216651368",
                  "3814986502092304",
                  "14544636039226909",
                  "55534064877048198",
                  "212336130412243110",
                  "812944042149730764",
                  "3116285494907301262",
                  "11959798385860453492",
                  "45950804324621742364",
                  "176733862787006701400",
                  "680425371729975800390",
                  "2622127042276492108820",
                  "10113918591637898134020",
                  "39044429911904443959240",
                  "150853479205085351660700",
                  "583300119592996693088040",
                  "2257117854077248073253720",
                  "8740328711533173390046320",
                  "33868773757191046886429490",
                  "131327898242169365477991900",
                  "509552245179617138054608572",
                  "1978261657756160653623774456",
                  "7684785670514316385230816156",
                  "29869166945772625950142417512",
                  "116157871455782434250553845880",
                  "451959718027953471447609509424",
                  "1759414616608818870992479875972",
                  "6852456927844873497549658464312",
                  "26700952856774851904245220912664",
                  "104088460289122304033498318812080",
                  "405944995127576985730643443367112",
                  "1583850964596120042686772779038896",
                  "6182127958584855650487080847216336",
                  "24139737743045626825711458546273312",
                  "94295850558771979787935384946380125",
                  "368479169875816659479009042713546950",
                  "1440418573150919668872489894243865350",
                  "5632681584560312734993915705849145100",
                  "22033725021956517463358552614056949950",
                  "86218923998960285726185640663701108500",
                  "337485502510215975556783793455058624700",
                  "1321422108420282270489942177190229544600",
                  "5175569924646105559418940193995065716350",
                  "20276890389709399862928998568254641025700",
                  "79463489365077377841208237632349268884500",
                  "311496878311103321137536291518809134027240",
                  "1221395654430378811828760722007962130791020",
                  "4790408930363303911328386208394864461024520",
                  "18793142726809884575211361279087545193250040",
                  "73745243611532458459690151854647329239335600",
                  "289450081175264899454283846029490767264392230",
                  "1136359577947336271931632877004667456667613940",
                  "4462290049988320482463241297506133183499654740",
                  "17526585015616776834735140517915655636396234280",
                  "68854441132780194707888052034668647142985206100",
                  "270557451039395118028642463289168566420671280440",
                  "1063353702922273835973036658043476458723103404520",
                  "4180080073556524734514695828170907458428751314320",
                  "16435314834665426797069144960762886143367590394940",
                  "64633260585762914370496637486146181462681535261000",
                  "254224158304000796523953440778841647086547372026600",
                  "1000134600800354781929399250536541864362461089950800",
                  "3935312233584004685417853572763349509774031680023800",
                  "15487357822491889407128326963778343232013931127835600",
                  "60960876535340415751462563580829648891969728907438000",
                  "239993345518077005168915776623476723006280827488229600",
                  "944973797977428207852605870454939596837230758234904050",
                  "3721443204405954385563870541379246659709506697378694300",
                  "14657929356129575437016877846657032761712954950899755100",
                  "57743358069601357782187700608042856334020731624756611000",
                  "227508830794229349661819540395688853956041682601541047340",
                  "896519947090131496687170070074100632420837521538745909320",
                 };


int main()
{
    int n;
    while(cin>>n,n!=-1)
    {
        cout<<num[n]<<endl;
    }
    return 0;
}

  

HDU 1134 Game of Connections(卡特蘭數)