1 /* 2 LA 3177 3 《训练指南》 4 思维的考察,积累下来,锻炼思维感。 5 */ 6 #include <iostream> 7 #include <cmath> 8 #include <algorithm> 9 #include <string.h> 10 #include <stdio.h> 11 #include <set> 12 #include <stack> 13 #include <vector> 14 #define maxn 100010 15 #define INF 999999999 16 using namespace std; 17 18 int lf[maxn],rg[maxn]; 19 int N,L,R; 20 int r[maxn]; 21 bool isok(int k){//测试k个是否可以 22 //固定坐标 23 int ll=r[1],rr=k-r[1]; 24 lf[1]=r[1];rg[1]=0; 25 for(int i=2;i<=N;i++){ 26 if (i % 2 == 1){ 27 rg[i]=min(r[i],rr-rg[i-1]);//本身要放的个数,右边剩下的空位 28 lf[i]=r[i]-rg[i];//剩下的肯定都放在左边 29 } 30 if (i % 2 == 0){//尽量在1号划分的区间的左边放置 31 lf[i]=min(r[i],ll-lf[i-1]); 32 rg[i]=r[i]-lf[i]; 33 } 34 } 35 //判断1和n是否有重合的部分 36 //偶数号向前取,奇数号向后取,才能更可能达成下面的条件 37 if (lf[N]==0) return true;else return false; 38 } 39 void solve(){ 40 // cout<<L<<","<<R<<endl; 41 if (N==1) {//一定要记得测试小数据 42 printf("%d ",r[1]); 43 return ; 44 } 45 if (N % 2 == 0) { 46 printf("%d ",L); 47 return ; 48 } 49 while(L<R){ 50 int M=L+(R-L)/2;//开始时二分写错了 51 if (!isok(M)) L=M+1;else R=M; 52 } 53 printf("%d ",L); 54 } 55 int main(){ 56 while(~scanf("%d",&N) && N){ 57 L=-1,R=-1; 58 for(int i=1;i<=N ;i++){ 59 scanf("%d",&r[i]); 60 } 61 r[N+1]=r[1]; 62 for(int i=1;i<=N;i++){ 63 L=max(L,r[i]+r[i+1]); 64 R=max(R,r[i]*3);//这个值最终肯定会等于最大的r的3倍,那么左中右三个都会分配到 65 } 66 solve(); 67 } 68 return 0; 69 }