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\n", 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;

}

 

你可能感兴趣的:(code)