注:本文为洛谷用户 zhangsenhao6728(也就是我)的题解,已提交成功。
题意理解
有 n n n 小杯饮料,要用这些饮料装满容量为 s s s 升的大杯(小 FN 能喝下去吗),问是否能装满,若可以,要求装满后小杯饮料中的饮料量最小的那一杯的饮料量尽量大(有点拗口)。
思路讲解
首先求出 n n n 杯饮料的总升数,若小杯的总升数还不到大杯的升数,那一定装不满,直接输出 − 1 -1 −1。
若能装满,进行如下操作,设第 i i i 个小杯的饮料量为 a i a_i ai:
- 找到小杯最小饮料量,设最小饮料量的小杯编号为 m i n min min。
- 遍历每个杯子,使每个小杯倒出 a i − a m i n a_i-a_{min} ai−amin,也就是使每个小杯的饮料量变成 a m i n a_{min} amin(不用管大杯有没有倒满,反正最小饮料量不会变)。
- 遍历完后有两种情况,第一种是大杯已经倒满了,这时小杯的最小饮料量为 a m i n a_{min} amin,直接输出 − 1 -1 −1;大杯若没有倒满,就是第二种情况,继续进行下面的操作。
- 你需要进行多次操作,每次操作就是使每个小杯倒出 1 1 1 升到大杯里,若当前操作后大杯装满了,那么最小饮料量就是 a m i n − d a_{min}-d amin−d,这里设 d d d 为操作次数,注意:如果 a m i n − d < 0 a_{min}-d<0 amin−d<0,那么也要输出 − 1 -1 −1。当然你可以用一道算式来表示操作次数,设大杯还未装的升数为 L L L: d = ⌈ L n ⌉ d=\lceil\frac{L}{n}\rceil d=⌈nL⌉,因为每次操作都是 n n n 个小杯倒 1 1 1 升,也就是每次操作倒 1 × n = n 1\times n=n 1×n=n 升。
你们最爱的 AC 代码
#include<bits/stdc++.h>
using namespace std;
int a[1001];
int main(){
long long s;
int minn=1000000001;
int n;
cin>>n>>s;
for(int i=1;i<=n;i++){
cin>>a[i];
minn=min(minn,a[i]);
}
for(int i=1;i<=n;i++){
s-=(a[i]-minn);
}
if(s<=0){
cout<<minn;
return 0;
}
s=ceil(s*1.0/n);
if(s>minn){
cout<<-1;
}else{
cout<<minn-s;
}
return 0;
}