zoukankan      html  css  js  c++  java
  • [AHOI2012]树屋阶梯

    同步: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,0,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,0,sizeof(t));
    			siz=0;
    		}
    		
    		bigNum(long long x){
    			memset(t,0,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('
    ');
    		}
    		
    		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 %d
    ",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,0,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,0,sizeof(t));
    			siz=0;
    		}
    		
    		bigNum(long long x){
    			memset(t,0,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('
    ');
    		}
    		
    		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;
    		}
    };
    
    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;
    }
    
  • 相关阅读:
    翻译MDN里js的一些方法属性
    ajax相关
    我的面试错题
    写代码通用思路
    工厂模式
    cookie & session
    X-UA-Compatible设置IE浏览器兼容模式
    [转]IE6/IE7/IE8/IE9中tbody的innerHTML不能赋值的完美解决方案
    EasyUseCase 一款脑图转化 Excel 测试用例工具 (1.2 版本升级)
    XMind2TestCase:一个高效测试用例设计的解决方案!
  • 原文地址:https://www.cnblogs.com/buringstraw/p/10328070.html
Copyright © 2011-2022 走看看