- 题目
题目描述
有n名选手参加比赛,从1∼n编号。每场比赛由两位选手对决,失败的被淘汰。为了增加比赛的观赏性,举办方并不想比赛双方实力相差太大的,所以决定,每场比赛的两位选手,之前胜场次数之差不能超过1。同时,鸡贼的举办方又不想冠军选手比赛太少了(严重影响比赛收入),希望冠军选手比赛场次越多越好。作为选手的你,当然不希望夺冠路上比赛场次太多,请问在这个赛制下,冠军最多比赛多少场?
输入
存在不超过10000组样例。每行一个整数n(1≤n≤1018)。
输出
每行输出一个样例的结果,为一个整数。
样例输入
1
2
3
10
1000000000000000000
样例输出
0
1
2
4
85
样例解释
我们假定冠军是1号。
第3个样例,1号依次击败2和3号。
第4个样例,其中一种比赛路线是1击败2,3击败4,1击败3,5击败6,1击败5,7击败8,9击败10,7击败9,1击败7。
- 解法
我们先来看一下1位选手、2位选手、3位选手和4位选手的比赛情况。
可以发现选手都是叶子节点,且不是叶子节点的节点的度均为2。冠军选手的比赛场数就是树的高度假设h代表树的高度,g(h)代表树的叶子节点数,可以发现g(h) = g(h-1)+g(h-2)(斐波拉契数列)。然后我们就可以用斐波拉契数列来解决这道题了。我的代码如下。
#include <cstdio>
#include <iostream>
typedef unsigned long long ull;
ull arr[100];
using namespace std;
int main(int argc, char const **argv) {
ull max = 1000000000000000000;
ull n;
ull f1 = 1, f2 = 2;
arr[0] = f1;
arr[1] = f2;
int cnt = 2, i;
//计算斐波那契数列
while(f2 <= max) {
f1 = f1 + f2;
arr[cnt++] = f1;
f2 = f2 + f1;
arr[cnt++] = f2;
}
while(cin >> n) {
for(i = 0; arr[i] <= n; i++);
cout << i-1 << endl;
}
return 0;
}