您的位置:首页 > 其它

HDU1865 1sting

2016-05-28 08:57 225 查看
问题链接:HDU1865 1sting,与问题“HDU5686
Problem B”几乎是同一个问题。

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

对于由所有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的程序如下:

/* HDU1865 1sting */

#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, count;
char c;

scanf("%d\n", &n);
while(n--) {
count = 0;
while((c=getchar()) != '\n')
count++;

fib(count);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: