题目描述
有n个人要进行比赛,比赛规则如下:
假设每轮比赛的人是m,取最大的k,k=2^t且k≤m。这k个人每2人举行一场比赛,胜利者进入一下轮,失败者被淘汰。
余下的m-k个人,不进行比赛,直接进入下一轮
直到决出冠军,比赛结束。
比如有5个人参加比赛,第一轮举办2场,剩余3人进入第二轮,第二轮1场,剩余2人进入第三轮,第三轮举办1场决出冠军,所以一共要办4场比赛。 请问一共要举行几轮多少场比赛?
输入
第一行是一个整数K,表示样例的个数。 以后每行一个样例,为n(1≤n≤1000000000)
输出
每行输出两个整数,轮数和比赛场数,中间用一个空格隔开。
样例输入
2 1 5样例输出
0 0 3 4
解题思路:本题只要题目意思读懂,思路就出来了。
每轮 找到 k 的值,然后进行 k/2 场比赛, 淘汰 k/2 个人, 还剩下 m - k/2 个人, 进入下一轮。循环往复,直到决出第一名(剩下最后一人)。
记录好 循环的轮数 和 比赛的场数,答案轻松得出。
怎么简单方便的找到最接近 m 的 k ? 笔者的方法是进行打表,先把2^x 的值 依次存入 数组中。之后就可以在数组表里比较查找出这个k啦。
AC代码:
#include <stdio.h>
int main()
{
int pow2[35] = {1,2};
int K,m,s,i = 1;
int cnt,num; // cnt 是比赛轮数,num 是 比赛场数
while (pow2[i] < 1e9) // 打表
{
i ++;
pow2[i] = 2*pow2[i-1];
}
scanf("%d",&K);
while ( K --)
{
scanf("%d",&m);
cnt = num = 0;
while ( m != 1) // 循环决出冠军
{
for ( i = 0; pow2[i] <= m; i ++); // 找到最接近m的k
s = i-1; // 因为for循环性质, k = 2^s 才是最接近m的
// 2^i 已经 > m
cnt ++, num += pow2[s]/2;
m = m-pow2[s]/2;
}
printf("%d %d\n",cnt,num);
}
return 0;
}
文章描述了一种比赛规则,每轮比赛基于2的幂次淘汰选手,直至决出冠军。解题思路涉及找到最接近m的2的幂次k,并通过打表方法优化查找过程。AC代码展示了C语言的解决方案,通过循环和数组来计算比赛的轮数和场数。
6316

被折叠的 条评论
为什么被折叠?



