您的位置:首页 > 其它

【算法设计与分析】长城守卫

2016-06-30 17:20 351 查看
【题目】



【输入输出】



【源代码】

<span style="font-family:Microsoft YaHei;font-size:24px;">#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=100010;
int n,r[maxn],left[maxn],right[maxn];

//测试p个礼物是否足够
//left[i]是第i个人拿到的“左边的礼物”总数,right同样
bool test(int p)
{
int x=r[1],y=p-r[1];
left[1]=x;
right[1]=0;
for(int i=2;i<=n;i++)
{
if(i%2==0)
{
right[i]=min(y-right[i-1],r[i]);//尽量拿右边的礼物
left[i]=r[i]-right[i];
}
else
{
left[i]=min(x-left[i-1],r[i]);//尽量拿左边的礼物
right[i]=r[i]-left[i];
}
}
return left
==0;
}

int main()
{
int n;
while(scanf("%d",&n)==1&&n)//输入人数,当输入为0时停止输入
{
for(int i=1;i<=n;i++)
scanf("%d",&r[i]);//输入第i个人想要的礼物数

r[n+1]=r[1];//形成环的条件

int L=0,R=0;

for(int i=1;i<=n;i++)
L=max(L,r[i]+r[i+1]);//选出相邻的礼物组合最多的

if(n%2==1)//如果为奇数
{
for(int i=1;i<=n;i++)
R=max(R,r[i]*3);//设定上界
while(L<R)
{
int M=L+(R-L)/2;//采用二分法缩小范围
if(test(M))
R=M;
else
L=M+1;
}
}
printf("%d\n",L);
}
return 0;
}

/*
3
4
2
2
5
2
2
2
2
2
5
1
1
1
1
1
0
*/
</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法