专栏文章
题解:P12167 不用二分
P12167题解参与者 4已保存评论 4
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mip40owo
- 此快照首次捕获于
- 2025/12/03 05:48 3 个月前
- 此快照最后确认于
- 2025/12/03 05:48 3 个月前
开头介绍:
该题解为本蒟蒻第一个题解,不用二分做法,想用二分的见其他题解。
注意:本文中“!”表感叹。
题目分析:
大概看一下题目就可以知道:其实就是同种颜色的水在倒来倒去。
这里就要注意了:题目中说:
因此他规定如果第 个瓶子和第 个瓶子中的水颜色相同并且满足 ,即可将任意整数单位的水从第 个水瓶倒出,倒入第 个水瓶中。
所以:只能从左往右倒,不能反过来。
右边的水不能倒过来,就不能增加同种颜色中前 个杯子的水的总量。所以,前 个水的总量的最大值就是这 个数的和。那么,这 个数的最小值的最大值就是他们的平均数。
我们找出的数必须满足大于等于所有平均数。所以,这个数就是所有平均数的最小值。
算法解析
首先:我们建一个类,来记录一种颜色中目前的前缀和以及杯子数。
CPPstruct Node { //用于表示每种颜色的情况
long long sum=0,cnt=0; //sum前缀和 cnt数量
} s[M];
接下来,输入 和 后,按顺序输入每个 的值。将 加到对应颜色的 中,并使 加1。
CPPfor(int i=1; i<=n; i++) {
cin>>a[i];
s[i%k].sum+=a[i];
s[i%k].cnt++;
最后求出平均值并更新 即可。
完整代码如下:
CPP//luogu P12167
#include <bits/stdc++.h>
using namespace std;
const int M=100010;
struct Node { //用于表示每种颜色的情况
long long sum=0,cnt=0; //sum前缀和 cnt数量
} s[M];
long long n,k;
long long a[M],ans=1e9;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>k;
for(int i=1; i<=n; i++) {
cin>>a[i];
s[i%k].sum+=a[i];
s[i%k].cnt++;
ans=min(s[i%k].sum/s[i%k].cnt,ans);
}
cout<<ans;
return 0;
}
复杂度 ,
代码长度应该没有更短的了吧。
相关推荐
评论
共 4 条评论,欢迎与作者交流。
正在加载评论...