poj2506(递推+高精度)

题目链接:http://poj.org/problem?id=2506

题目大意:给出一个n,代表一个2*n的矩形地板,要求只用2*1和2*2两种瓷砖将其完全覆盖,求所有情况的数量

解题思路;求出递推公式:f(n)=2*f(n-2)+f(n-1),这道题还有另外一个关键点是高精度,因为题目提到n可能会达到250,因此答案的数字将会非常大,long long型照样会爆掉,因此采用数组模拟加法和乘法,开始的时候把第24行:if(c.num[len+1]!=0)c.len=len+1;写成了if(c.num[len+1]!=0)c.len++;导致计算错误,找了很久才发现问题,全是泪……一定要细心啊

AC代码:

#include <iostream>
#include <cstring>
using namespace std;
struct bignum{
    int len,num[1000];
}dp[255];
void add(bignum a,bignum b,bignum &c)
{
    int len = a.len>b.len?a.len:b.len;
    for(int i=1;i<=len;i++)
    {
        c.num[i] = a.num[i]+b.num[i];
    }
//    for(int i=len;i>=1;i--)cout<<c.num[i];
//    cout<<endl;
    for(int i=1;i<=len;i++)
    {
        if(c.num[i]>9)
        {
            c.num[i]-=10;
            c.num[i+1]++;
        }
    }
    if(c.num[len+1]!=0)c.len=len+1;
    else c.len = len;
}
void multi2(bignum &x)
{
    int len = x.len;
    for(int i=1;i<=len;i++)
    {
        x.num[i]*=2;
    }
    for(int i=1;i<=len;i++)
    {
        if(x.num[i]>9)
        {
            x.num[i]-=10;
            x.num[i+1]++;
        }
    }
    if(x.num[len+1]!=0)x.len++;
}
int main()
{
    int n;

/*    dp[0].len=1;
    dp[0].num[1]=1;
    dp[1].len=1;
    dp[1].num[1]=1;
    for(int i=2;i<=250;i++)
    {
        multi2(dp[i-2]);
        add(dp[i-2],dp[i-1],dp[i]);
    }*/
    while(cin>>n)
    {
        memset(dp,0,sizeof(dp));
        dp[0].len=1;
        dp[0].num[1]=1;
        dp[1].len=1;
        dp[1].num[1]=1;
        for(int i=2;i<=n;i++)
        {
            multi2(dp[i-2]);
            add(dp[i-2],dp[i-1],dp[i]);
        }
        for(int i=dp[n].len;i>=1;i--)
        {
            cout<<dp[n].num[i];
        }
        cout<<endl;
    }
    return 0;
}


你可能感兴趣的:(算法,ACM,杭电)