您的位置:首页 > 大数据 > 人工智能

HDU 1023 Train Problem II (卡特兰数,经典)

2015-06-07 23:12 381 查看
题意:

  给出一个数字n,假设火车从1~n的顺序分别进站,求有多少种出站序列。

思路:

  卡特兰数的经典例子。n<101,用递推式解决。需要使用到大数。n=100时大概有200位以下。

#include <bits/stdc++.h>
using namespace std;
const int N=101;
vector<string>  vect;
void _mult(string num1, string num2, string &result )
{
reverse(num1.begin(),num1.end());    //反转
reverse(num2.begin(),num2.end());
result="";
int i, j, re_int[200];    //********这里的150是位数,根据需要可以增大或减小*********
memset(re_int, 0, sizeof(re_int));
for(i=0; i<num1.length(); i++)    //两串作乘法,结果存放于re_int数组中, 最多可达150位!
for(j=0; j<num2.length(); j++)
re_int[i+j] += ((num1[i]-48) * (num2[j]-48));
int jinwei=0, zhi;
for(i=0; i<num1.length()+num2.length(); i++)    //单独处理进位问题,上一步中的数组每个元素都有可能超过10的,所以没处理进位
{
zhi = re_int[i]+jinwei;
re_int[i] = zhi%10;
jinwei = zhi/10;
}
for(i=num1.length()+num2.length()-1; i>=0; i--)    //将i打个标记,数组re_int的前面部分可能全0,要去掉
if(re_int[i]!=0)    break;
for(;i>=0;i--)    //将整型数组转成字符串
result = result+(char)(re_int[i]+48);
if(result=="")    //若结果还是空,乘法的结果是0?
result="0";
}
void div(char * src,int n,char *dest)
{
int len = strlen(src),i,k,t=0,s=0;
bool flag = true;    //商是否有了第一个有效位,防止商首部一直出现0
for(i=0,k=0; i<len; i++)
{
t = s*10+(src[i]-48);    //新余数
if(t/n>0 || t==0)        //余数为0要修改商
{
dest[k++] = t/n+48,s = t%n,flag = false;
}
else                    //不够除,修改余数
{
s = t;
if(!flag)            //商已经有有效位了,补零
dest[k++] = '0';
}
}
dest[k]='\0';
}

void precal()
{
string s="1";
vect.push_back(s);
vect.push_back(s);
char c[200], dest[200];
for(int i=2; i<101; i++)
{
string q1="",res;
int a=4*i-2; //第一个括号
while(a)
{
q1+=(a%10+'0');
a/=10;
}
reverse(q1.begin(),q1.end());
_mult(q1,vect[i-1],res);    //乘法
strcpy(c,res.c_str());
div(c,i+1,dest);            //除法
s=dest;
vect.push_back(dest);
}
}
int main()
{
//freopen("e://input.txt", "r", stdin);
int n;
precal();
while(~scanf("%d", &n))
cout<<vect
<<endl;
return 0;
}


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