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;
}
posted @ 2017-02-18 21:06  despair_ghost  阅读(339)  评论(0编辑  收藏  举报