1. 程式人生 > >poj 2018 Best Cow

poj 2018 Best Cow

由於偉大的poj上並沒有中文翻譯,所以我就從另一個網站上扒來了中文版 題目描述

給定一個長度為 n 的非負整數序列 A ,求一個平均數最大的,長度不小於 L 的子段。

輸入格式 第一行用空格分隔的兩個整數 n 和 L; 第二行為 n 個用空格隔開的非負整數,表示 Ai 輸出格式 輸出一個整數,表示答案的 100010001000 倍。不用四捨五入,直接輸出。 樣例 樣例輸入 10 6 6 4 2 10 3 8 5 9 4 1 樣例輸出 6500 資料範圍與提示 1≤n≤10^5,0≤A​i​​≤2000。

這道題可以二分平均數的大小,然後在當前情況下把每一位都減去平均數,這樣問題就變成了找一個非負的長度不小於L的子序列和,順便再用字首和維護一下。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n,L;
double a[100003] ,b[100003],f[100003];
int main()
{
 scanf("%d%d",&n,&L);
 for(int i = 1;i <= n;i++)
 {
  scanf("%lf",&a[i]);
 }
 double x = 1e-5;//表示精度為10^-5
 double l = -1e6,r = 1e6;
 while(r - l > x)
 {
  double mid = (l + r) / 2;
  for(int i = 1;i <= n;i++)
  {
   b[i] = a[i] - mid;
  }
  for(int i = 1;i <= n;i++)
  {
   f[i] = f[i - 1] + b[i];
  }
  double ans = -1e7;
  double s = 1e7;
  for(int i = L;i <= n;i++)
  {
   s = min(s,f[i - L]);//最小的字首
   ans = max(ans,f[i] - s);//不斷更新期間和知道找到最大的 
  }
  if(ans >= 0)l = mid;
  else r = mid; 
 }
 printf("%d",int(r * 1000));
 return 0;
} 

受到了來自隔壁大佬的薰陶,我也立志要成為一個勤更部落格的人(哇嘔)