Codeforces 1452b Toy Blocks

Codeforces 1452b Toy Blocks

题目描述:
You are asked to watch your nephew who likes to play with toy blocks in a strange way.
He has n boxes and the i-th box has ai blocks. His game consists of two steps:
he chooses an arbitrary box i;
he tries to move all blocks from the i-th box to other boxes.
If he can make the same number of blocks in each of n−1 other boxes then he will be happy, otherwise, will be sad. Note that your nephew can only move the blocks from the chosen box to the other boxes; he cannot move blocks from the other boxes.
You don’t want to make your nephew sad, so you decided to put several extra blocks into some boxes in such a way that no matter which box i he chooses he won’t be sad. What is the minimum number of extra blocks you need to put?


题目大意

有n个盒子,每个盒子里有若干个积木,现在需要在这些积木中再添加一些积木,使得当每次取出任何一个盒子中的所有积木并将这些积木分配到另外的n-1个盒子中时都能使得n-1个盒子中每个盒子里的积木数相等。求出要添加的积木的最小数量。

思路

为了方便起见,我们可以把整个数据画成一个类似直方图的图形:
图片替换文本

让图上每一个块的高度表示对应盒子中积木的数量。把积木数量最大的那个盒子里面的积木数设为 max 。

现在我们要取出一块经行分配,先不考虑有最大数量的那一个盒子。对于其他小于max的盒子,当我们取出来分配的时候,首先肯定是不能分配到max上面的(因为我们要做的是将 n-1 个盒子里的数量变为相等并且最小化要添加的数量,如果添加到 max 上,就会需要更多的块来添加到其余的盒子里面来达到max的大小)。所以最好的办法就是分配完之后让所有 n-1 个盒子里面的积木数可以等于 max。
图片替换文本

假设我们已经添加完了题目总所询问的添加数目,这是我们取出 a[i] 号块经行分配,也就是将 a[i] 填充到上图绿色方框的区域内。所以说一定有 a[i]= 绿色方框的大小。而我们还可以发现,a[i] 的大小加上红色方框的大小正好是等于 max 。所以说绿色方框的大小加上红色方框的大小正好等于 max 。这也就是我们添加积木时要达到的目标。

现在我们退回没有添加时候的状态。这时我们就可以很容易推断出只要添加 max*(n-1)- sum 块就可以了。

图片替换文本

但是这里还有一个问题,当max*(n-1)< sum 的时候,这里也就是说,没有添加的情况下方框上方那个一块空白的部分已经小于max了。这时,在没添加之前,当我们选择其中的一个并分到另外的 n-1 个盒子里面的的时候,不仅每个盒子的数量会等于 max ,而且还会多出来一些(无法使得所有n-1个相等),这些多出来的会使得分配还是没有满足条件。这里究竟多出来多少呢?也就是max%(n-1)块。所以我们需要补(n-1)-max%(n-1)块就能满足题意了。

实现代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<functional>
using namespace std;
int main(){
	ios::sync_with_stdio(false);
	long long t,n,tmp,maxx;
	long long sum;
	cin>>t;
	while(t--){
		cin>>n;
		maxx=0,sum=0;
		for(int i=0;i<n;i++){
			cin>>tmp;
			maxx=max(maxx,tmp);
			sum+=tmp;//找到最大值并计算总和
		}
		if(maxx*(n-1)>sum)cout<<maxx*(n-1)-sum<<endl;
		else{
			if(sum%(n-1)==0){
				cout<<0<<endl; //在sum是n-1的倍数的情况下就说明不用补了,自动满足条件
			}else{
				cout<<(n-1)-sum%(n-1)<<endl;
			}
		}
	}
 
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值