vijos 1894 二分

题意:在 Ninian 的花园里,有许多琼花,环绕着中间的凉亭。有 N 片琼花,组成一个环。Ninian 想在凉亭中发动 [セチの祈り] , 需要划分出三个区域的琼花,为了平均,要最大化面积最小的区域的面积。划分区域:即用三刀把这个环分成三段,每段称之为一个区域。

链接:点我

最大化最小,显然是二分,在判断答案的过程中用贪心

 
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 #define MOD 1000000007
10 const int INF=0x3f3f3f3f;
11 const double eps=1e-5;
12 typedef long long ll;
13 #define cl(a) memset(a,0,sizeof(a))
14 #define ts printf("*****\n");
15 const int MAXN=200100;
16 int n,m,tt;
17 ll sum[MAXN],a[MAXN];
18 bool check(ll x)
19 {
20     int mid=0,last=0;
21     for(int i=0;i<n;i++)    //枚举起点,这里用的是贪心策略,每次尽量选大一点的面积
22     {
23         while(i+n>=mid&&sum[mid]-sum[i]<x)  mid++;
24         while(i+n>=last&&sum[last]-sum[mid]<x)  last++;
25         if(sum[i+n]-sum[last]>=x)  return true;
26     }
27     return false;
28 }
29 int main()
30 {
31     int i,j,k;
32     /*#ifndef ONLINE_JUDGE
33     freopen("1.in","r",stdin);
34     #endif*/
35     while(~scanf("%d",&n))
36     {
37         cl(sum);
38         for(i=1;i<=n;i++)
39         {
40             scanf("%lld",a+i);
41             sum[i]=sum[i-1]+a[i];
42         }
43         for(i=1;i<=n;i++)
44         {
45             sum[i+n]=sum[i+n-1]+a[i];
46         }
47         ll l=0,r=100000000000000,ans=0;
48 
49         while(l<=r)
50         {
51             ll mid=(l+r)>>1;
52             if(check(mid))
53             {
54                 ans=mid;
55                 l=mid+1;
56             }
57             else r=mid-1;
58         }
59         printf("%lld\n",ans);
60     }
61 }

 

posted @ 2015-05-16 09:49  miao_a_miao  阅读(162)  评论(0编辑  收藏  举报