HDU 1134 Game of Connections(卡特兰数)

Posted 韵祈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1134 Game of Connections(卡特兰数)相关的知识,希望对你有一定的参考价值。

题目代号: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(卡特兰数)的主要内容,如果未能解决你的问题,请参考以下文章

HDU5973 Game of Geting Stone(威佐夫博弈)

HDU-5578 Friendship of Frog

HDU - 5973 Game of Taking Stones (威佐夫博弈 高精度)

HDU 5514 Game of Flying Circus

HDU-1134 卡特兰数+java大数模板

HDU 2216 Game III(BFS)