NC53179. 年轮蛋糕
描述
输入描述
第1行有一个整数N,表示年轮蛋糕上有N个切口;接下来有N行,第行有一个整数,表示第i个切口和第i+1个切口之间部分(当i=N时即为第N个和第1个之间部分)的大小。
输出描述
输出一行,一个整数,表示当把年轮蛋糕切成3块之后最小块大小的最大值。
示例1
输入:
6 1 5 4 5 2 4
输出:
6
说明:
示例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; }