[AHOI2012]树屋阶梯
发布时间:2020-12-14 05:13:26 所属栏目:大数据 来源:网络整理
导读:同步:http://buringstraw.win/index.php/archives/17/ 题目 输入格式:一个正整数N(1=N=500),表示阶梯的高度。输出格式:一个正整数,表示搭建方法的个数。(注:搭建方法的个数可能很大) 分析 通过 人肉打表找规律 严格证明发现这是个卡特兰数 然后要
同步:http://buringstraw.win/index.php/archives/17/ 题目输入格式: 一个正整数N(1<=N<=500),表示阶梯的高度。 输出格式: 一个正整数,表示搭建方法的个数。(注:搭建方法的个数可能很大) 分析通过 然后要求到第500项#(喷) 所以这同时也是个优秀的高精度板子 Code首先是高精度部分(两个板子的codemix) struct bigNum{ private: short t[1005];int siz; public: bigNum(string a){ memset(t,sizeof(t)); int len=a.size(); for(int i=0;i<a.size();++i){ t[len-i]=a[i]; } siz=len; } bigNum(void){ memset(t,sizeof(t)); siz=0; } bigNum(long long x){ memset(t,sizeof(t)); int ws=0; while(x){ ++ws; int q=x%10; x/=10; t[ws]=q; } siz=ws; } void print(void){ for(int i=siz;i>=1;--i){ putchar(t[i]+'0'); } putchar('n'); } int size(void){ return siz; } friend bigNum operator *(bigNum a,long long b){ bigNum c; int len=a.size()+20,g=0; for(int i=1;i<=len;++i){ c.t[i]=a.t[i]*b; } for(int i=1;i<=len;++i){ if(c.t[i]>9){ c.t[i+1]+=c.t[i]/10; c.t[i]=c.t[i]%10; } } while(len>1&&c.t[len]==0)--len; c.siz=len; return c; } friend bigNum operator *(long long b,bigNum a){ return a*b; } friend bigNum operator *(bigNum a,bigNum b){ bigNum c; int len=a.size()+b.size(); for(int i=1;i<=a.size();++i){ for(int j=1;j<=b.size();++j){ c.t[i+j-1]+=(a.t[i]*b.t[j]); } } for(int i=1;i<=len;++i){ if(c.t[i]>9){ c.t[i+1]+=c.t[i]/10; c.t[i]=c.t[i]%10; } } while(len>1 && c.t[len]==0)len--; c.siz=len; return c; } friend bigNum operator /(bigNum a,long long b){ bigNum c; int k=a.size(),g=0; for(int i=k;i>0;--i){ g=g*10+a.t[i]; c.t[i]=g/b; g%=b; } while(k>1&&c.t[k]==0)--k; c.siz=k; return c; } friend bigNum operator /(long long b,bigNum a){ return a/b; } friend bigNum operator +(bigNum a,bigNum b){ bigNum c; int g=0,k=max(a.size(),b.size()); for(int i=1;i<=k;i++){ c.t[i]=a.t[i]+b.t[i]+g; g=c.t[i]/10; c.t[i]%=10; } if(g>0){ c.t[++k]=g; } c.siz=k; return c; } }; 然后是卡特兰数部分, 这道题很玄学的地方在于,用递归在我这里会RE,在洛谷和cqyzoj上就不会。。。
更正:用太过诡异的递推 递归求法(公式2): bigNum ktl(int x){ if(x<=0)return 0; if(x==1)return 1; if(k[x].size())return k[x]; else return k[x]=(4*x-2)*ktl(x-1)/(x+1); } “太过诡异的”递推求法(公式1): bigNum ktl(int n){ for(int i=2;i<=n;++i){ for(int j=0;j<i;++j){ // printf("%d %dn",i,j); k[i]=k[i]+(k[j]*k[i-j-1]); //ans.print(); } } return k[n]; } (k的声明): bigNum k[510]={(bigNum)1,(bigNum)1}; 以下为完整代码 #include<iostream> #include<cstdio> #include<cstring> using namespace std; struct bigNum{ private: short t[1005];int siz; public: bigNum(string a){ memset(t,b.size()); for(int i=1;i<=k;i++){ c.t[i]=a.t[i]+b.t[i]+g; g=c.t[i]/10; c.t[i]%=10; } if(g>0){ c.t[++k]=g; } c.siz=k; return c; } }; bigNum k[510]={(bigNum)1,(bigNum)1}; /*bigNum ktl(int x){ if(x<=0)return 0; if(x==1)return 1; if(k[x].size())return k[x]; else return k[x]=(4*x-2)*ktl(x-1)/(x+1); }*/ bigNum ktl(int n){ for(int i=2;i<=n;++i){ k[i]=(4*i-2)*k[i-1]/(i+1); } return k[n]; } int main(void){ int n; cin>>n; ktl(n).print(); // bigNum a(123),b(45); // (a*b).print(); return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |