1. 洛谷P3407 散步
2. 洛谷P2678 跳石头 (P2678的题解有个大佬讲的很好,忘可自查)
3. POJ3974:学哈希时遇到的一道马拉车模板题->[O(n)],可以用“哈希+二分”->[O(nlogn)]
(听说哈希和二分很配?)(´ー∀ー`)
Solve
求连续子段的最大平均数,要求长度不小于L
—>二分答案,判定“是否存在一个长度不小于L的子段,平均值不小于二分的值”
—>数列每个元素减去二分值,判定“是否存在一个长度不小于L的子段,子段和非负”
—>求一个长度不小于L的最大子段和(@《最大子序列》)
(TIPS:由于平均数为double类型,所以二分while需要配置EPS = 1e-5之类,注意数据类型)(另外之前在while里MS()TLE了?,罪过)
Code
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #pragma warning (disable:4996) 2 #include <algorithm> 3 #include <iostream> 4 #include <iomanip> 5 #include <cstring> 6 #include <string> 7 #include <cstdio> 8 #include <queue> 9 #include <stack> 10 #include <cmath> 11 #include <map> 12 #include <set> 13 using namespace std; 14 typedef long long ll; 15 #define MS(x) memset(x,0,sizeof(x)) 16 #define inf 0x3f3f3f3f 17 const int maxn = 1e6 + 10; 18 19 double n[maxn]; 20 double initn[maxn];//将每个原区间元素都减去二分值 21 double sum[maxn] = { 0 };//求区间和一般用前缀和相减 22 23 int main() 24 { 25 int N, F; 26 scanf("%d %d", &N, &F); 27 for (int i = 1; i <= N; i++) 28 scanf("%lf", &n[i]); 29 double eps = 1e-5; 30 double l = 0, r = 1e6; 31 while (r - l > eps) 32 { 33 double mid = (l + r) / 2; 34 for (int i = 1; i <= N; i++) 35 initn[i] = n[i] - mid; 36 for (int i = 1; i <= N; i++) 37 sum[i] = sum[i - 1] + initn[i]; 38 double ans = -0x7f7f7f7f; 39 double mi = 0x7f7f7f7f; 40 for (int i = F; i <= N; i++)//以后常看看呀~ 41 { 42 mi = min(sum[i - F], mi); 43 ans = max(ans, sum[i] - mi); 44 } 45 if (ans >= 0) 46 l = mid; 47 else 48 r = mid; 49 } 50 printf("%d", int(r * 1000)); 51 return 0; 52 }