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位选手的比赛情况。
    一位选手
    两位选手
    三位选手
    四位选手
    可以发现选手都是叶子节点,且不是叶子节点的节点的度均为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;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值