1. 程式人生 > >POJ2018 Best Cow Fences

POJ2018 Best Cow Fences

大堆 分享圖片 else bsp eps 技術 簡單 can mes

實數折磨人啊啊啊啊啊啊啊

好,實數應該是最反人類的東西了......

這個害得我調了0.5天才過。

大意是這樣的:給你一個數列,求其中不少於f個的連續數的最大平均值。

不禁想起寒假的課程來...

此處應該二分ans,每次把數列減去ans後判斷是否有不少於f的一段sum>=0

大喜過望,寫了個二分,然後發現不會O(1)判斷...

冥思苦想無果之後不由得去看題解。發現要維護前綴和和1~i-f+1的最小前綴和即可。

然後就被實數卡了一天。。。

最後發現還是寫的樸素點好。要相信出題人頭腦簡單不會拿一大堆if來寫二分。

AC代碼:

技術分享圖片
 1 #include <cstdio>
 2 #include <algorithm>
 3
using namespace std; 4 const int INF = 0x7f7f7f7f, N = 100010; 5 const double eps = 1e-5; 6 int f[N], n, F; 7 double a[N]; 8 bool check(double k) { 9 for(int i=1;i<=n;i++) { 10 a[i] = f[i] - k; 11 a[i] += a[i-1]; 12 } 13 double small = 0, sum=0; // small != INF, small = 0 14
for(int i = F; i <= n; i++) { 15 sum = a[i] - small; 16 if(sum >= 0) { 17 return true; 18 } 19 small = min(small, a[i-F+1]); 20 } 21 return false; 22 } 23 24 int main() { 25 //freopen("in.in","r",stdin); 26 //freopen("my.out","w",stdout);
27 scanf("%d%d",&n,&F); 28 int large = -INF, small = INF; 29 for(int i=1;i<=n;i++) { 30 scanf("%d",&f[i]); 31 large = max(large, f[i]); 32 small = min(small, f[i]); 33 } 34 double l = small, r = large, mid; 35 while(r-l>eps) { 36 //printf("%.10lf %.10lf \n",l,r); 37 mid = (l + r) / 2; 38 if(check(mid)) { 39 l = mid; 40 } 41 else { 42 r = mid; 43 } 44 } 45 46 printf("%d",(int)(r*1000)); 47 return 0; 48 }
AC代碼在此

POJ2018 Best Cow Fences