Codeforces Round #763 (Div. 2) C. Balanced Stone Heaps(弱鸡分析)
思路
正解是二分答案+贪心,很多人可能不明白为何检验的时候能从后往前检验,这里来分析一波。对于每次二分枚举到的最小值 x x x , 我们要保证每一堆石头的数量最后都 ≥ x \geq x ≥x ,如果从前往后分配,对于当前堆的石头数量 a i a_i ai , 我们无法知道该分配多少给 a i − 1 , a i − 2 a_{i-1}, a_{i-2} ai−1,ai−2 ,也无法知道分配了 a i a_i ai以后能不能再让 a i ≥ x a_i \geq x ai≥x。如果从后往前, 如果当前 b i ≤ x b_i \leq x bi≤x, 那么这次二分不合法, 否则我们在 ( b i − x ) 3 \frac {(b_i -x )}{3} 3(bi−x) 和 a i 3 \frac {a_i}{3} 3ai之间取一个最小值分配给 b i − 1 b_{i-1} bi−1 和 b i − 2 {b_{i-2}} bi−2,肯定不能小于 a i 3 \frac {a_i}{3} 3ai,不然你拿什么分配给前面的。最后再判断 b 1 b_1 b1 和 b 2 b_2 b2满足条件与否即可。
AC代码
#include<bits/stdc++.h>
#define ll long long
#define rep(i,x,y) for(int i=x; i<=y; i++)
#define per(i,x,y) for(int i=x; i>=y; i--)
using namespace std;
const int N = 2e5+9;
ll a[N],b[N];
int n;
bool check(ll x){
rep(i,1,n) b[i]=a[i];
per(i,n,3){
if(b[i]<x) return 0;
ll d = min((b[i]-x)/3,a[i]/3);
b[i]-=3*d;
b[i-1]+=d;
b[i-2]+=2*d;
}
return b[1]>=x&&b[2]>=x;
}
int main(){
int t;
cin>>t;
while(t--){
scanf("%d",&n);
rep(i,1,n) scanf("%d",a+i);
ll l=1,r=1e18;
ll ans=0;
while(l<=r){
ll mid = (l+r)>>1;
if(check(mid)) {
ans=mid;
l=mid+1;
}
else r=mid-1;
}
printf("%lld\n",ans);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话