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; }