Hihocoder #1095 : HIHO Drinking Game (微软苏州校招笔试)( *【二分搜索最优解】)

#1095 : HIHO Drinking Game

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

Little Hi and Little Ho are playing a drinking game called HIHO. The game comprises N rounds. Each round, Little Hi pours T milliliter of water into Little Ho's cup then Little Ho rolls a K-faces dice to get a random number d among 1 to K. If the remaining water in Little Ho's cup is less than or equal to d milliliter Little Hi gets one score and Little Ho drinks up the remaining water, otherwise Little Ho gets one score and Little Ho drinks exactly d milliliter of water from his cup. After N rounds who has the most scores wins.

Here comes the problem. If Little Ho can predict the number d of N rounds in the game what is the minimum value of T that makes Little Ho the winner? You may assume that no matter how much water is added, Little Ho's cup would never be full.

输入

The first line contains N(1 <= N <= 100000, N is odd) and K(1 <= K <= 100000).
The second line contains N numbers, Little Ho's predicted number d of N rounds.

输出

Output the minimum value of T that makes Little Ho the winner.

样例输入
5 6
3 6 6 2 1
样例输出
4

题目分析:输入n个数,这n个掷的筛子数的大小范围是:[1, k].也就是大一行输入的两个数n,k;
现在要找到一个最小的T 让小ho赢了小hi。
规则如下:进行n轮,看谁的总分最高谁赢。
每次都会往杯子里加T的水,如果当前杯子里的水<=此次掷得筛子数
小,hi分数++,小ho全喝光
如果当前杯子里的水<此次掷的筛子数,ho分数++,
小ho喝掉对应此次筛子数量的水
最后谁的分高谁赢。

代码:
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <math.h>
#include <cctype>
#include <algorithm>

using namespace std;
//枚举T
//如果d>=杯子里的水, hi++, ho全喝光
//如果 d<杯子里的水, ho++, ho喝掉d的量
//枚举区间[1, k+1]
int a[100001];
int n;

bool Drink_t(int t) //测试看看每次t的水,小ho能不能赢?
{
    int hi=0, ho=0;
    int cnt=0; //代表杯子里的水
    for(int i=0; i<n; i++)
    {
        cnt+=t;
        if(a[i]>=cnt)
        {
            hi++;
            cnt=0;
        }
        else if( a[i]<cnt )
        {
            ho++;
            cnt=cnt-a[i];
        }
    }
    if(hi>ho)
        return false; //表示输了
    else
        return true; //表示赢了
}

void B_search(int low, int high)
{
    int mid;
    while(low<=high)
    {
        mid=(low+high)/2;
        if( Drink_t(mid)==true && Drink_t(mid-1)==false ) //只有当前这个mid可以赢,一旦mid-1就不能赢了,这个答案才是最小的
        {
            break;
        }
        else if(Drink_t(mid)==true)
        {
            high=mid-1;
        }
        else if(Drink_t(mid)==false )
        {
            low=mid+1;
        }
    }
    printf("%d
", mid );
}

int main()
{
    int k;
    while(scanf("%d %d", &n, &k)!=EOF )
    {
        for(int i=0; i<n; i++)
            scanf("%d", &a[i]);
        B_search(1, k+1);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/yspworld/p/4253106.html