列表

详情


NC53179. 年轮蛋糕

描述

译自 JOI 2014 Final T3「バームクーヘン
JOI君马上要和妹妹JOI子和JOI美一起吃小吃。今天的小吃是他们三个人都很喜欢的年轮蛋糕。
年轮蛋糕是像下图一样呈圆筒形的蛋糕。为了把蛋糕分给三个人,JOI君必须沿着半径方向切3刀,从而把蛋糕分成三块。然而,由于年轮蛋糕硬得像实木一样,要让刀切进去并不简单。因此,这个年轮蛋糕上事先准备了N个切口,而JOI君只能在有切口的位置下刀。切口按顺时针顺序编号为1到N,对于,第i个切口和第i+1个切口之间部分的大小是。第N个切口和第1个切口之间部分的大小是
Baumkuchen1.png图1:一个年轮蛋糕的例子,妹控的JOI君在把蛋糕切成3块之后,自己选走最小的一块吃掉,把剩下两块分给两个妹妹。而另一方面,JOI君太喜欢年轮蛋糕了,只要能吃到的时候就会想吃很多很多。试求:JOI君吃掉的蛋糕的大小至多不超过多少。
给出切口个数N和表示各部分大小的整数,请求出把年轮蛋糕切成3块之后最小一块大小的最大值。

输入描述

第1行有一个整数N,表示年轮蛋糕上有N个切口;接下来有N行,第行有一个整数,表示第i个切口和第i+1个切口之间部分(当i=N时即为第N个和第1个之间部分)的大小。

输出描述

输出一行,一个整数,表示当把年轮蛋糕切成3块之后最小块大小的最大值。

示例1

输入:

6
1
5
4
5
2
4

输出:

6

说明:

Baumkuchen2.png

示例2

输入:

30
1
34
44
13
30
1
9
3
7
7
20
12
2
44
6
9
44
31
17
20
33
18
48
23
19
31
24
50
43
15

输出:

213

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 52ms, 内存消耗: 3536K, 提交时间: 2021-02-13 09:32:05

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<stack>
#define in(a) a=read()
#define MAXN 200020
#define REP(i,k,n) for(long long i=k;i<=n;i++)
using namespace std;
inline long long read()
{
	long long x=0,f=1;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar())
	if(ch=='-')
	f=-1;
	for(;isdigit(ch);ch=getchar())
	x=x*10+ch-'0';
	return x*f; 
}
long long n;
long long ans;
long long a[MAXN],s[MAXN];
inline bool check(long long i,long long k)
{
	long long sum=s[i+k-1]-s[i-1];
	long long loc=i+k-1;
	long long left=0,right=n;
	while(right-left>1)
	{
		long long mid=(right+left)/2;
		if(s[loc+mid]-s[loc]<sum&&s[i+n-1]-s[loc+mid]<sum)
		return 0;
		if(s[loc+mid]-s[loc]<sum)
		left=mid;
		if(s[i+n-1]-s[loc+mid]<sum)
		right=mid;
		if(s[loc+mid]-s[loc]>=sum&&s[i+n-1]-s[loc+mid]>=sum)
		return 1;
	}
	return 0;
}

int main()
{
	in(n);
   REP(i,1,n)
   {
   	in(a[i]);
   	a[i+n]=a[i];
   	s[i]=s[i-1]+a[i];
   }
   REP(i,1,n)
   s[n+i]=s[i+n-1]+a[i+n];
   REP(i,1,n)
   {
   	long long left=0,right=n;
   	while(right-left>1)
   	{
   		long long mid=(left+right)/2;
   		if(check(i,mid))
   		left=mid;
   		else
   		right=mid;
	   }
	   ans=max(s[i+left-1]-s[i-1],ans);
   }
   cout<<ans;
   return 0;
}

上一题