蓝桥集训之最佳牛围栏
-
核心思想:二分+双指针
- 利用二分找到平均值avg 在cows中每个元素求前缀和时减去一个avg
- 最终只要找到一个大于F的区间和>=0即可
- 题目要求找出>=F的区间 用双指针:mins保留sum[i]及以前的最小值
- mins代表的元素的下标一定不会超过i 所以用sum[j] - mins的区间长度一定>=F
- 利用二分找到平均值avg 在cows中每个元素求前缀和时减去一个avg
-
#include <iostream> #include <cmath> using namespace std; const int N = 100010; int n, m; int cows[N]; double sum[N]; bool check(double mid) { for(int i=1;i<=n;i++) sum[i] = sum[i-1] + cows[i] - mid; //根据元素>0<0判断 double mins = 0; for(int i=0,j=m;j<=n;j++,i++) { mins = min(mins,sum[i]); //取sum[i]以前的最小值 if(sum[j] >= mins) return true; //sum[j]-mins>=0 } return false; } int main() { cin>>n>>m; double l=0,r=0; for(int i=1;i<=n;i++) { cin>>cows[i]; r = max(r,double(cows[i])); } while(r-l > 1e-5) //精度 { double mid = (l+r) /2; if(check(mid)) l=mid; else r = mid; } cout<<int(r*1000); }