• PKU 2506 Tiling(递推+高精度||string应用)


    题目大意:原题链接
    有2×1和2×2两种规格的地板,现要拼2×n的形状,共有多少种情况,首先要做这道题目要先对递推有一定的了解。
    解题思路:
    1.假设我们已经铺好了2×(n-1)的情形,则要铺到2×n则只能用2×1的地板

    2.假设我们已经铺好了2×(n-2)的情形,则要铺到2×n则可以选择1个2×2或两个2×1,故可能有下列三种铺法

               

      其中要注意到第三个会与铺好2×(n-1)的情况重复,故不可取,故可以得到递推式

      a[n]=2*a[n-2]+a[n-1];

      然后就是高精度部分,可直接用高精度的模板

    解法一:递推+高精度

    #include<cstring>
    #include<iostream>
    using namespace std;
    
    const int Base=1000000000;  
    const int Capacity=100;  
        
    struct BigInt{  
         int Len;  
         int Data[Capacity];  
         BigInt():Len(0){}  
         BigInt(const BigInt &V):Len(V.Len) {memcpy(Data,V.Data,Len*sizeof*Data);}  
         BigInt(int V):Len(0) {for(;V>0;V/=Base) Data[Len++]=V%Base;}  
         BigInt &operator=(const BigInt &V) {Len=V.Len;memcpy(Data,V.Data,Len*sizeof*Data);return *this;}  
         int &operator[] (int Index) {return Data[Index];}  
         int operator[] (int Index) const {return Data[Index];}  
    };
    
    BigInt operator+(const BigInt &A,const BigInt &B){  
         int i,Carry(0);  
         BigInt R;  
         for(i=0;i<A.Len||i<B.Len||Carry>0;i++){  
             if(i<A.Len) Carry+=A[i];  
             if(i<B.Len) Carry+=B[i]; 
             R[i]=Carry%Base;  
             Carry/=Base;  
         }  
         R.Len=i;  
         return R;  
    }
    
    ostream &operator<<(ostream &Out,const BigInt &V){  
         int i;  
         Out<<(V.Len==0?0:V[V.Len-1]);  
         for(i=V.Len-2;i>=0;i--) 
             for(int j=Base/10;j>0;j/=10) 
                 Out<<V[i]/j%10;  
         return Out;  
    }
    
    int main()
    {
        int n;
        BigInt a[250];
        a[0]=1,a[1]=1;
        for(int i=2;i<=250;i++)
            a[i]=a[i-2]+a[i-2]+a[i-1];
        while(cin>>n)
            cout<<a[n]<<endl;
        return 0;
    }

    解法二:递推+String应用(模拟)

    #include<cstring>
    #include<iostream>
    using namespace std;
    int n;
    string a[300];
    string Add(string s1,string s2)
    {
        if(s1.length()<s2.length())
            swap(s1,s2);
        for(int i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--){
            s1[i]=s1[i]+(j>=0?s2[j]-'0':0);//不够则补上前导零 
            if(s1[i]-'0'>=10){//判断进位 
                s1[i]=(s1[i]-'0')%10+'0';//加上字符'0'将s1[i]还原为字符 
                if(i) s1[i-1]++;
                else s1='1'+s1;//分情况考虑进位加一 
            }
        }
        return s1;
    }
    int main()
    {
        a[0]="1",a[1]="1";
        for(int i=2;i<=250;i++)
            a[i]=Add(Add(a[i-1],a[i-2]),a[i-2]);
        while(cin>>n)
           cout<<a[n]<<endl;
        return 0;
    }
  • 相关阅读:
    理解事件驱动select,poll,epoll三种模型
    谈谈对线程与进程的理解
    5-3.首行缩进
    5-2.行高
    5-1.字间距
    4-6.字体样式重置
    4-5.字体风格
    4-4.字体粗细
    4-3.字体颜色设置
    4-2.字体设置
  • 原文地址:https://www.cnblogs.com/freinds/p/6414115.html
Copyright © 2020-2023  润新知