CF 628A --- Tennis Tournament --- 水题

  CF 628A

  题目大意:给定n,b,p,其中n为进行比赛的人数,b为每场进行比赛的每一位运动员需要的水的数量,

       p为整个赛程提供给每位运动员的毛巾数量,

       每次在剩余的n人数中,挑选2^k=m(m <=n)个人进行比赛,剩余的n-m个人直接晋级,

       直至只剩一人为止,问总共需要的水的数量和毛巾的数量

  解题思路:毛巾数很简单: n*p即可

       水的数量:1,2,4,8,16,32,64,128,256,512,提前打成一个表,

       根据当前剩余的人数n在表中二分查找最大的小于等于n的数,结果即为本次进行比赛的人数,记为a[pos]

       根据a[pos]计算相应的水的数量,并用n-a[pos]/2(淘汰人数)以进行下一轮的计算,直至n为1

/* CF 628A --- Tennis Tournament --- 水题 */
#include <cstdio>
#include <algorithm>
using namespace std;

int a[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 };

//在a的{x,y)中查找小于等于key的第一个位置
int BinarySearch(int x, int y, int key){
    while (x < y){
        int mid = x + (y - x) / 2;
        if (a[mid] <= key && a[mid + 1] > key){
            return mid;
        }
        else if (a[mid] > key){
            y = mid;
        }
        else{
            x = mid+1;
        }
    }
    return -1;
}

int main()
{
#ifdef _LOCAL
    freopen("D:input.txt", "r", stdin);
#endif
    int n, b, p;

    while (scanf("%d%d%d", &n, &b, &p) == 3){
        int sum = 0;
        int t = n;
        while (t != 1){
            //查找当前t个人需要多少人进行比赛
            int pos = BinarySearch(0, 9, t); //a[pos]即为比赛人数的 a[pos]/2为裁判数
            sum += (a[pos] * b + a[pos] / 2);
            t -= (a[pos] / 2);    //减去淘汰的a[pos]/2即为剩余人数
        }
        printf("%d %d
", sum, n*p);
    }

    return 0;
}
View Code

       

原文地址:https://www.cnblogs.com/tommychok/p/5370484.html