【Codeforces】Codeforces Round #202 (Div. 1) A. Mafia | 数学

41 阅读2分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

【Codeforces】Codeforces Round #202 (Div. 1) A. Mafia | 数学

题目链接

Problem - 348A - Codeforces

题目

One day nn friends gathered together to play "Mafia". During each round of the game some player must be the supervisor and other n1n - 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 aia_i 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?

题目大意

一天有 nn 个人想玩游戏,其中第 ii 个人想至少参与 aia_i 次游戏,但是每轮游戏至多有 n1n-1 人可以参加。

对于给定的 a1,a2,...,ana_1,a_2,...,a_n,试求最少举办多少次游戏,才能使得对于所有的 1in1\le i \le n,第 ii 个人参与游戏的次数不小于 aia_i

思路

最好情况是,每轮游戏都有 n1n-1 个人参与,且不存在 ii 使得第 ii 个人参与游戏的次数大于 aia_i。在这种情况下也必须要进行 i=1nain1\lceil\frac{\sum_{i=1}^n a_i}{n-1}\rceil 次游戏。考虑在什么情况下举行上述次数游戏无法满足所有人的条件。

容易发现只要存在一个人想玩游戏的次数非常多,以至于大于 i=1nain1\lceil\frac{\sum_{i=1}^n a_i}{n-1}\rceil,就说明我们认为在某些次游戏中有两个他参与,这显然不合题意。所以答案不应该小于 max{a1,a2,...,an}\max\{a_1,a_2,...,a_n\}。此时答案是什么呢?
假设 a1a2a3...ana_1\le a_2\le a_3 \le...\le a_n,则

an>i=1nain1an>i=1nain1(n1)an>i=1nai(n1)ani=2nai>a1(n2)ani=2n1ai>a1i=2n1(anai)>a1a_n>\lceil\frac{\sum_{i=1}^n a_i}{n-1}\rceil\\ a_n>\frac{\sum_{i=1}^n a_i}{n-1}\\ (n-1)a_n>\sum_{i=1}^n a_i\\ (n-1)a_n-\sum_{i=2}^n a_i>a_1\\ (n-2)a_n-\sum_{i=2}^{n-1} a_i>a_1\\ \sum_{i=2}^{n-1}(a_n-a_i)>a_1

此时 anaia_n-a_i 表示在满足条件的情况下 ana_n 轮游戏中 aia_i 最多可以不参加的轮数,则如果 ana_n 轮游戏中第 22n1n-1 个人一共可以不参加游戏的轮数大于 a1a_1,第一个人就可以参加 ana_n 轮游戏中的 a1a_1 次。所以当 max{a1,a2,...,an}>i=1nain1\max\{a_1,a_2,...,a_n\}>\lceil\frac{\sum_{i=1}^n a_i}{n-1}\rceil 时,答案是 max{a1,a2,...,an}\max\{a_1,a_2,...,a_n\}

否则显然可以合理安排大家参与游戏的时机,在 i=1nain1\lceil\frac{\sum_{i=1}^n a_i}{n-1}\rceil 轮游戏里满足大家的需求。

代码

#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
long long a[100001];
int main()
{
	int n;
	long long cnt=0;
	scanf("%d",&n);
	for (int i=1;i<=n;++i)
	{
		scanf("%lld",&a[i]);
	}
	sort(a+1,a+1+n);
	long long sum=a[1]+a[n];
	for (int i=2;i<n;++i)
	{
		cnt+=a[n]-a[i];
		sum+=a[i];
	}
	printf("%lld\n",max(a[n],(sum+n-2)/(n-1)));
//	if (cnt>=a[1]) printf("%lld\n",a[n]);
//	else printf("%lld\n",);
	return 0;
}