#include <stdio.h>
long long qn(long long n);
long long main() {
long long n;
scanf("%lld", &n);
printf("%lld", qn(n));
}
long long qn(long long n) {
long long x;
if (n <= 3) {
x = 1;
}
else {
x = qn(n-1)+qn(n-2)+qn(n-3);
}
return x;
}
这道题由于数值不断累加,最后结果超出了C/C++所有基本类型所能表示的数值范围,即使long long也不够用,因此你得用高精度大数运算来实现。另外你也不能用递归,因为如果递归层次太多,很容易导致栈溢出,应该改用循环来实现。
下面是我用C++实现的例子,你可以参考一下,把代码改成C语言应该不难。
从运行结果可以看出,
当n=100时,qn(100)=69087442470169316923566147,就已经超出了long long的数值范围了。
当n=1000时,qn(1000)=1056569942836970422279284954750098236519342255152919675406067018213960747393817667095588725995948973722417422227477589614070393820954716814070302286673551230293560940674846367367520224538342482630207080905846768675790903553645664897731604869996342518016379904334431
#include <iostream>
#include <string>
#include <iterator>
#include <vector>
#include <cassert>
class BigInt
{
public:
BigInt(unsigned int n = 0)
{
if (n == 0)
_data.push_back('0');
else
{
while (n)
{
_data.push_back(n % 10 + '0');
n /= 10;
}
}
}
BigInt(const std::string &s) : _data(s.rbegin(), s.rend()) {}
BigInt &operator+=(const BigInt &other);
BigInt operator+(const BigInt &other) const
{
BigInt t = *this;
t += other;
return t;
}
private:
std::string _data;
friend std::istream &operator>>(std::istream &is, BigInt &a);
friend std::ostream &operator<<(std::ostream &os, const BigInt &a);
};
BigInt &BigInt::operator+=(const BigInt &other)
{
int carry = 0;
std::string::iterator itr1 = _data.begin();
std::string::const_iterator itr2 = other._data.begin();
while (itr1 != _data.end() && itr2 != other._data.end())
{
int a = *itr1 - '0';
int b = *itr2 - '0';
int c = a + b + carry;
carry = c / 10;
c %= 10;
*itr1 = c + '0';
++itr1;
++itr2;
}
while (itr1 != _data.end())
{
int a = *itr1 - '0' + carry;
carry = a / 10;
a %= 10;
*itr1 = a + '0';
++itr1;
}
while (itr2 != other._data.end())
{
int a = *itr2 - '0' + carry;
carry = a / 10;
a %= 10;
_data.push_back(a + '0');
++itr2;
}
if (carry > 0)
_data.push_back(carry + '0');
return *this;
}
std::istream &operator>>(std::istream &is, BigInt &a)
{
std::string s;
is >> s;
a = s;
return is;
}
std::ostream &operator<<(std::ostream &os, const BigInt &a)
{
std::copy(a._data.rbegin(), a._data.rend(), std::ostream_iterator<char>(os));
return os;
}
BigInt qn(int n)
{
assert(n >= 1);
BigInt q[3] = {1, 1, 1}, r = 1;
for (int i = 4; i <= n; i++)
{
r = q[2];
r += q[1];
r += q[0];
q[0] = q[1];
q[1] = q[2];
q[2] = r;
}
return r;
}
int main()
{
int n;
std::cin >> n;
std::cout << qn(n) << std::endl;
return 0;
}
$ g++ -Wall main.cpp
$ ./a.out
100
69087442470169316923566147
$ ./a.out
1000
1056569942836970422279284954750098236519342255152919675406067018213960747393817667095588725995948973722417422227477589614070393820954716814070302286673551230293560940674846367367520224538342482630207080905846768675790903553645664897731604869996342518016379904334431
首先,奇怪的是,你的main怎么能返回long long呢?
兄弟,数学很重要啊,你难以想象这个函数调用次数增长的速度,你输入100,计算多少次,我也说不清楚,可能需要几亿亿亿亿亿次!不可能像20以下那样秒出结果!要是不出意外,运行程序的时候,你应该听到电脑发出很大的声音,因为计算量太大了!再说,稍微有点常识就知道,第100项的话,long long远远不够,你的计算机内存都不一定能存的下那么大的数字!
这个不是你的机器有问题,而是你这个程序是个递归算法,而是特别耗时,计算量特别大。你按不动是因为计算机在底层进行运算,由于数据巨大,运算时间比较长,建议把代码修改一下或者数值小点