蓝书1.2 二分和三分

T1 poj 2018 

题目大意:

一个数列 求一个平均数最大的 长度不长于L的子串

思路:

二分一个值 x  假设这个数为平均值

则当所有数列都减去这个值时 若剩余数列中长度不小于L的最大子串非负 则l=mid

最大子串可以表示为一段前缀和减去之前一段最小的前缀和且长度大于L

就可以O n 来check

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 101010
12 #define eps 1e-5
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int n,m,a[MAXN];
22 double g[MAXN],sum[MAXN];
23 int check(double x)
24 {
25     for(int i=1;i<=n;i++) g[i]=(double)a[i]-x;
26     for(int i=1;i<=n;i++) sum[i]=sum[i-1]+g[i];
27     double minn=1e10,res=-1;
28     for(int i=m;i<=n;i++)
29         minn=min(minn,sum[i-m]),res=max(res,sum[i]-minn);
30     return res>=0;
31 }
32 int main()
33 {
34     n=read(),m=read();
35     for(int i=1;i<=n;i++) a[i]=read();
36     double l=0,r=1e10,mid;
37     while(r-l>=eps)
38     {
39         mid=(l+r)/2.0;
40         if(check(mid)) l=mid;
41         else r=mid;
42     }
43     printf("%d\n",(int)(r*1000));
44 }
View Code

T2 数列分段2

题目大意:

一个数列 分成m段使每段和最大的最小

思路:

二分一个值x 判断是否可以使数列被分成m段 每段小于x

判断时 暴力判断即可

T3 扩散

题目大意:

每个点在下一个时间单位都会向四个方向扩散

求所有点最短多长时间会形成一个联通块

思路:

二分时间判断是否可以连边 

并查集check是否形成一个联通块

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 101010
12 #define eps 1e-5
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 struct node {int x,y;}g[MAXN];
22 int n,f[MAXN];
23 int find(int x) {return x==f[x]?x:f[x]=find(f[x]);}
24 int check(int x)
25 {
26     for(int i=1;i<=n;i++) f[i]=i;
27     int res=n;
28     for(int i=1;i<=n;i++)
29         for(int j=i+1;j<=n;j++)
30             if(abs(g[i].x-g[j].x)+abs(g[i].y-g[j].y)<=2*x)
31                 if(find(i)!=find(j)) f[f[i]]=f[j],res--;
32     return res==1;
33 }
34 int main()
35 {
36     n=read();
37     for(int i=1;i<=n;i++) g[i].x=read(),g[i].y=read();
38     int l=0,r=1e9,mid,ans;
39     while(r>=l)
40     {
41         mid=(l+r)>>1;
42         if(check(mid)) ans=mid,r=mid-1;
43         else l=mid+1;
44     }
45     printf("%d\n",ans);
46 }
View Code

T4 灯泡

题解链接

T5 传送带

题解链接

猜你喜欢

转载自www.cnblogs.com/yyc-jack-0920/p/9285878.html