XTUOJ-1286-比赛

  1. 题目

题目描述
有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. 解法
    我们先来看一下1位选手、2位选手、3位选手和4位选手的比赛情况。
    XTUOJ-1286-比赛_第1张图片
    XTUOJ-1286-比赛_第2张图片
    XTUOJ-1286-比赛_第3张图片
    XTUOJ-1286-比赛_第4张图片
    可以发现选手都是叶子节点,且不是叶子节点的节点的度均为2。冠军选手的比赛场数就是树的高度假设h代表树的高度,g(h)代表树的叶子节点数,可以发现g(h) = g(h-1)+g(h-2)(斐波拉契数列)。然后我们就可以用斐波拉契数列来解决这道题了。我的代码如下。
#include 
#include 
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;
}

你可能感兴趣的:(XTUOJ)