【算法设计与分析】长城守卫
2016-06-30 17:20
351 查看
【题目】
![](http://img.blog.csdn.net/20160630171911660?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
【输入输出】
![](http://img.blog.csdn.net/20160630171940490?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
【源代码】
<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>
【输入输出】
【源代码】
<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>
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- C#算法函数:获取一个字符串中的最大长度的数字
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 经典排序算法之冒泡排序(Bubble sort)代码
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法