• HDU5686 Problem B


    问题链接HDU5686 Problem B

    问题简述:参见上述链接。

    问题分析这个问题几乎与“HDU1865 1sting”是同一个问题。

    这个问题看似一个字符串排列问题,然而只是计算排列数量,可以用斐波拉契数列来解。

    对于由所有1构成的字符串而言,用f(n)表示其长度为n时的可能数,有以下的情形:

    长度为1时,即“1”,无法合并,只有1种可能;

    长度为2时,即“11”,只有一种合并方法,字符串可以变为“11”,或“2”,有2种可能;

    长度为n时,它的长n-1的串与1连接有f(n-1)种情况,或者它的第n-1个1与第n个1合并为2,有f(n-2)种可能,合计有f(n-2)+f(n-1)种可能。

    以上可以看出,这是一个典型的斐波拉契数列。

    然而,斐波拉契数列值的增长速度太快了,需要构筑一个大整数类来解决。这里给出的程序只是简单地实现了只有+运算的无符号大整数类,解决本问题是没有问题的。

    程序说明:(略)。

    AC的程序如下:

    /* HDU5686 Problem B */
    
    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <sstream>
    
    using namespace std;
    
    // 无符号整数类,整数放在字符串中,可以用整数初始化。只有加运算功能。
    class UBigInt {
    private:
        string num;
    public:
        UBigInt();
        UBigInt(int n);
        void setNumber(string s);
        const string& getNumber(); // retrieves the number
        UBigInt operator + (UBigInt b);
    private:
        string add(string number1, string number2);
    };
    
    UBigInt::UBigInt() { // empty constructor initializes zero
        num = "0";
    }
    
    UBigInt::UBigInt(int n) {
        stringstream ss;
        string s;
        ss << n;
        ss >> s;
        setNumber(s);
    }
    
    void UBigInt::setNumber(string s) {
        num = s;
    }
    
    const string& UBigInt::getNumber() { // retrieves the number
        return num;
    }
    
    UBigInt UBigInt::operator + (UBigInt b) {
        UBigInt addition;
        addition.setNumber( add(getNumber(), b.getNumber() ) );
    
        return addition;
    }
    
    string UBigInt::add(string number1, string number2) {
        string add = (number1.length() > number2.length()) ?  number1 : number2;
    
        int diffLength = abs( (int) (number1.size() - number2.size()) );
        if(number1.size() > number2.size())
            number2.insert(0, diffLength, '0'); // put zeros from left
        else// if(number1.size() < number2.size())
            number1.insert(0, diffLength, '0');
    
        char carry = 0;
        for(int i=number1.size()-1; i>=0; --i) {
            add[i] = (carry+(number1[i]-'0')+(number2[i]-'0')) + '0';
    
            if(i != 0) {
                if(add[i] > '9') {
                    add[i] -= 10;
                    carry = 1;
                } else
                    carry = 0;
            }
        }
        if(add[0] > '9') {
            add[0]-= 10;
            add.insert(0,1,'1');
        }
        return add;
    }
    
    void fib(int n)
    {
        if(n == 1) {
            cout << 1 << endl;
        } else if(n == 2) {
            cout << 2 << endl;
        } else {
             UBigInt f1 = 1;
             UBigInt f2 = 2;
             UBigInt temp;
             n -= 2;
             while(n--) {
                 temp = f2;
                 f2 = f1 + f2;
                 f1 = temp;
             }
             cout << f2.getNumber() << endl;
        }
    }
    
    int main(void)
    {
        int n;
    
        while(scanf("%d", &n) != EOF) {
            fib(n);
        }
    
        return 0;
    }


  • 相关阅读:
    Spring AOP 注解开发
    AOP的专业术语
    Java自定义注解的实现和应用
    Spring 声明式事务管理
    另一种线程安全机制:在事务管理中起到巨大作用的 ThreadLocal
    MySQL的二级索引
    数据库的范式化和反范式化
    MySQL为表字段添加索引
    mysql索引(二)----如何高效使用索引
    Alexnet网络
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564817.html
Copyright © 2020-2023  润新知