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 }

 

你可能感兴趣的:(OS)