CodeForces - 348A Mafia (巧妙二分)

传送门:

http://codeforces.com/problemset/problem/348/A

A. Mafia
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

One day n friends gathered together to play "Mafia". During each round of the game some player must be the supervisor and other n - 1 people take part in the game. For each person we know in how many rounds he wants to be a player, not the supervisor: the i-th person wants to play ai rounds. What is the minimum number of rounds of the "Mafia" game they need to play to let each person play at least as many rounds as they want?

Input

The first line contains integer n (3 ≤ n ≤ 105). The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 109) — the i-th number in the list is the number of rounds the i-th person wants to play.

Output

In a single line print a single integer — the minimum number of game rounds the friends need to let the i-th person play at least ai rounds.

Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

Examples
Input
Copy
3
3 2 2
Output
Copy
4
Input
Copy
4
2 2 2 2
Output
Copy
3
Note

You don't need to know the rules of "Mafia" to solve this problem. If you're curious, it's a game Russia got from the Soviet times: http://en.wikipedia.org/wiki/Mafia_(party_game).

分析:

题目意思:

n个人,其中每个人最少参加Ai次比赛。比赛是这样定义的:n个人之中出1个裁判,其中n-1个人参加

问:最少需要多少场比赛可以满足题目要求?

做法:

把焦点聚集身上在裁判,不要聚集在玩家身上

因为每一局裁判只有一个嘛

假设一共玩了k局,那么某个人当裁判的局数最多就是k-a[i]

 (就是他玩够之后一直都在当裁判)

把所有人当裁判的最大值加起来,如果总值大于等于k

说明每一场比赛都可以找到裁判,(意味着k是可以的)

当前k可以就减小k呗,(左移)

当前k不可以就增加k呗(右移)

这就是二分的思想了

 

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define max_v 100005
LL a[max_v];
int n;
int f(LL mid)//判断当前局数是否满足要求
{
    LL cnt=0;
    for(int i=0;i<n;i++)
    {
        if(mid<a[i])
            return 0;//局数还小于玩家想玩的次数 那么局数肯定是不行的
        else
            cnt+=(mid-a[i]);
    }
    if(cnt>=mid)//所有玩家当裁判的最大值的和大于局数 意味着可以找到裁判 局数符合要求 但不一定是最小的符合要求的局数 所以需要二分
        return 1;
    return 0;
}

int main()
{
    LL maxc;
    LL ans;
    LL l,h,mid;
    while(cin>>n)
    {
        maxc=0;
        for(int i=0; i<n; i++)
        {
            scanf("%I64d",&a[i]);
            maxc=max(maxc,a[i]);
        }
        l=1;
        h=maxc*10;//*10是估算的 边界最多也这么大 找完了还找不到就再扩大点
        while(h-l>=0)
        {
            mid=(l+h)/2;
            if(f(mid))
            {
                ans=mid;
                h=mid-1;
            }else
            {
                l=mid+1;
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

 

 

 

 

 

 

 

posted @ 2018-07-25 12:27  西*风  阅读(503)  评论(0编辑  收藏  举报