hdu1134 Game of Connections(Catalan数, 顺便附上大数类模板)

来源:互联网 发布:ug软件是什么软件 编辑:程序博客网 时间:2024/05/21 22:56

Catalan数公式:

C[0] = 1

C[n] = C[n-1]*(4*n - 2)*(n+1)


代码取自kuangbin巨巨的模板

#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>using namespace std;/** 完全大数模板* 输出cin>>a* 输出a.print();* 注意这个输入不能自动去掉前导0的,可以先读入到char数组,去掉前导0,再用构造函数。*/#define MAXN 9999#define MAXSIZE 1010#define DLEN 4class BigNum{private:    int a[500]; //可以控制大数的位数    int len;public:    BigNum() {        len=1;    //构造函数        memset(a,0,sizeof(a));    }    BigNum(const int); //将一个int类型的变量转化成大数    BigNum(const char*); //将一个字符串类型的变量转化为大数    BigNum(const BigNum &); //拷贝构造函数    BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算    friend istream& operator>>(istream&,BigNum&); //重载输入运算符    friend ostream& operator<<(ostream&,BigNum&); //重载输出运算符    BigNum operator+(const BigNum &)const; //重载加法运算符,两个大数之间的相加运算    BigNum operator-(const BigNum &)const; //重载减法运算符,两个大数之间的相减运算    BigNum operator*(const BigNum &)const; //重载乘法运算符,两个大数之间的相乘运算    BigNum operator/(const int &)const; //重载除法运算符,大数对一个整数进行相除运算    BigNum operator^(const int &)const; //大数的n次方运算    int operator%(const int &)const; //大数对一个int类型的变量进行取模运算    bool operator>(const BigNum &T)const; //大数和另一个大数的大小比较    bool operator>(const int &t)const; //大数和一个int类型的变量的大小比较    void print(); //输出大数};BigNum::BigNum(const int b) //将一个int类型的变量转化为大数{    int c,d=b;    len=0;    memset(a,0,sizeof(a));    while(d>MAXN) {        c=d-(d/(MAXN+1))*(MAXN+1);        d=d/(MAXN+1);        a[len++]=c;    }    a[len++]=d;}BigNum::BigNum(const char *s) //将一个字符串类型的变量转化为大数{    int t,k,index,L,i;    memset(a,0,sizeof(a));    L=strlen(s);    len=L/DLEN;    if(L%DLEN)len++;    index=0;    for(i=L-1; i>=0; i-=DLEN) {        t=0;        k=i-DLEN+1;        if(k<0)k=0;        for(int j=k; j<=i; j++)            t=t*10+s[j]-'0';        a[index++]=t;    }}BigNum::BigNum(const BigNum &T):len(T.len) //拷贝构造函数{    int i;    memset(a,0,sizeof(a));    for(i=0; i<len; i++)        a[i]=T.a[i];}BigNum & BigNum::operator=(const BigNum &n) //重载赋值运算符,大数之间赋值运算{    int i;    len=n.len;    memset(a,0,sizeof(a));    for(i=0; i<len; i++)        a[i]=n.a[i];    return *this;}istream& operator>>(istream &in,BigNum &b){    char ch[MAXSIZE*4];    int i=-1;    in>>ch;    int L=strlen(ch);    int count=0,sum=0;    for(i=L-1; i>=0;) {        sum=0;        int t=1;        for(int j=0; j<4&&i>=0; j++,i--,t*=10) {            sum+=(ch[i]-'0')*t;        }        b.a[count]=sum;        count++;    }    b.len=count++;    return in;}ostream& operator<<(ostream& out,BigNum& b) //重载输出运算符{    int i;    cout<<b.a[b.len-1];    for(i=b.len-2; i>=0; i--) {        printf("%04d",b.a[i]);    }    return out;}BigNum BigNum::operator+(const BigNum &T)const //两个大数之间的相加运算{    BigNum t(*this);    int i,big;    big=T.len>len?T.len:len;    for(i=0; i<big; i++) {        t.a[i]+=T.a[i];        if(t.a[i]>MAXN) {            t.a[i+1]++;            t.a[i]-=MAXN+1;        }    }    if(t.a[big]!=0)        t.len=big+1;    else t.len=big;    return t;}BigNum BigNum::operator-(const BigNum &T)const //两个大数之间的相减运算{    int i,j,big;    bool flag;    BigNum t1,t2;    if(*this>T) {        t1=*this;        t2=T;        flag=0;    } else {        t1=T;        t2=*this;        flag=1;    }    big=t1.len;    for(i=0; i<big; i++) {        if(t1.a[i]<t2.a[i]) {            j=i+1;            while(t1.a[j]==0)                j++;            t1.a[j--]--;            while(j>i)                t1.a[j--]+=MAXN;            t1.a[i]+=MAXN+1-t2.a[i];        } else t1.a[i]-=t2.a[i];    }    t1.len=big;    while(t1.a[len-1]==0 && t1.len>1) {        t1.len--;        big--;    }    if(flag)        t1.a[big-1]=0-t1.a[big-1];    return t1;}BigNum BigNum::operator*(const BigNum &T)const //两个大数之间的相乘{    BigNum ret;    int i,j,up;    int temp,temp1;    for(i=0; i<len; i++) {        up=0;        for(j=0; j<T.len; j++) {            temp=a[i]*T.a[j]+ret.a[i+j]+up;            if(temp>MAXN) {                temp1=temp-temp/(MAXN+1)*(MAXN+1);                up=temp/(MAXN+1);                ret.a[i+j]=temp1;            } else {                up=0;                ret.a[i+j]=temp;            }        }        if(up!=0)            ret.a[i+j]=up;    }    ret.len=i+j;    while(ret.a[ret.len-1]==0 && ret.len>1)ret.len--;    return ret;}BigNum BigNum::operator/(const int &b)const //大数对一个整数进行相除运算{    BigNum ret;    int i,down=0;    for(i=len-1; i>=0; i--) {        ret.a[i]=(a[i]+down*(MAXN+1))/b;        down=a[i]+down*(MAXN+1)-ret.a[i]*b;    }    ret.len=len;    while(ret.a[ret.len-1]==0 && ret.len>1)        ret.len--;    return ret;}int BigNum::operator%(const int &b)const //大数对一个 int类型的变量进行取模{    int i,d=0;    for(i=len-1; i>=0; i--)        d=((d*(MAXN+1))%b+a[i])%b;    return d;}BigNum BigNum::operator^(const int &n)const //大数的n次方运算{    BigNum t,ret(1);    int i;    if(n<0)exit(-1);    if(n==0)return 1;    if(n==1)return *this;    int m=n;    while(m>1) {        t=*this;        for(i=1; (i<<1)<=m; i<<=1)            t=t*t;        m-=i;        ret=ret*t;        if(m==1)ret=ret*(*this);    }    return ret;}bool BigNum::operator>(const BigNum &T)const //大数和另一个大数的大小比较{    int ln;    if(len>T.len)return true;    else if(len==T.len) {        ln=len-1;        while(a[ln]==T.a[ln]&&ln>=0)            ln--;        if(ln>=0 && a[ln]>T.a[ln])            return true;        else            return false;    } else        return false;}bool BigNum::operator>(const int &t)const //大数和一个int类型的变量的大小比较{    BigNum b(t);    return *this>b;}void BigNum::print() //输出大数{    int i;    printf("%d",a[len-1]);    for(i=len-2; i>=0; i--)        printf("%04d",a[i]);    printf("\n");}BigNum f[110];//卡特兰数int main(){    f[0]=1;    for(int i=1; i<=100; i++)        f[i]=f[i-1]*(4*i-2)/(i+1);//卡特兰数递推式    int n;    while(scanf("%d",&n)==1) {        if(n==-1)break;        f[n].print();    }    return 0;}


高精度,支持乘法和加法

#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; struct BigInt {     const static int mod = 10000;     const static int DLEN = 4;     int a[600], len;     BigInt()     {         memset(a, 0, sizeof a );         len = 1;     }     BigInt(int v)     {         memset(a, 0, sizeof a );         len = 0;         do {            a[len++] = v % mod;            v /= mod;         }while(v);     }     BigInt(const char s[])     {         memset(a, 0, sizeof a );         int L = strlen(s);         len = L/DLEN;         if(L%DLEN) len++;         int index = 0;         for(int i= L-1;i >= 0; i -= DLEN)         {             int t = 0;             int k = i - DLEN + 1;             if(k < 0) k = 0;             for(int j = k;j <= i; ++j)                t = t*10 + s[j] - '0';             a[index++] = t;         }     }     BigInt operator + (const BigInt &b) const     {         BigInt res;         res.len = max(len,b.len);         for(int i = 0;i <= res.len;++i)            res.a[i] = 0;         for(int i = 0; i < res.len;++i)         {             res.a[i] += ((i < len)?a[i]:0) + ((i < b.len)?b.a[i]:0);             res.a[i+1] += res.a[i]/mod;             res.a[i] %= mod;         }         if(res.a[res.len] > 0) res.len++;         return res;     }     BigInt operator * (const BigInt &b)const     {         BigInt res;         for(int i = 0; i < len; ++i)         {             int up = 0;             for(int j = 0;j < b.len;++j)             {                 int temp = a[i]*b.a[j] + res.a[i+j] + up;                 res.a[i+j] = temp % mod;                 up = temp/mod;             }             if(up != 0)                res.a[i+b.len] = up;         }         res.len = len + b.len;         while(res.a[res.len - 1] == 0 && res.len > 1) res.len--;         return res;     }     void output()     {         printf("%d",a[len-1]);         for(int i = len-2; i >=0 ; i--)            printf("%04d",a[i]);         printf("\n");     } };int main(){    BigInt x, y;    char s1[1000],s2[1000];    scanf("%s%s",s1, s2);    x= BigInt(s1);    y = s2;    BigInt ans = x + y;    ans.output();    BigInt anssub = x * y;    anssub.output();    return 0;}


0 1
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 京东京准达超时怎么办 南京犬类免疫证怎么办 合肥犬类免疫证怎么办 快递号码写错了怎么办 网购下单后商家说没有货该怎么办 京东账号换手机怎么办 手机不发验证码怎么办 京东打白条分期付款额度不够怎么办 网易云音乐昵称被占用怎么办 ebay账号邮箱忘了怎么办 易贝账号邮箱忘了怎么办 运动鞋网上擦了黑鞋油怎么办 真皮鞋用水洗了怎么办 支付宝余额限额了怎么办 微信余额转账限额怎么办 微信充值话费充错了怎么办 京东白条月限额怎么办 淘手游上买的账号被找回了怎么办 手机看视频缓冲慢怎么办 wan口状态未连接怎么办 王者荣耀本地回放过期怎么办 qq邮件发错了怎么办 千叶钻戒换款怎么办 车钥匙掉厕所了怎么办 宿舍有个整晚磨牙的室友该怎么办 百度云照片压缩后模糊怎么办 手机点+号无法上传图片怎么办 支付宝账户支付功能关闭怎么办 一件衣服买小了怎么办 交行u盾密码忘了怎么办 老婆婚内出轨丈夫应该怎么办 微信小程序获取用户信息失败怎么办 拼多多砍价没有完成怎么办 微信人数上限了怎么办 微信5000人满了怎么办 微信朋友满了怎么办啊 失业金签到忘签怎么办 gec安全密码忘了怎么办 唯品会微信商城地址错怎么办跨省 电脑突然没网了怎么办 移动光猫只能连一台电脑怎么办