Hrbust 2294 修建传送门【思维】

修建传送门
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 56(14 users)Total Accepted: 12(10 users)Rating: Special Judge: No
Description

     做为长城上的卫士,影踪派一直守在螳螂高原上防止螳螂人卡拉克西的入侵。影踪派的长城可以近似看做是一条直线上依次编号为1~N的N个基地组成,编号相邻的两个基地之间由长城相连接,而影踪派掌门祝踏岚所在的影踪禅院位于编号为1的基地。
    祝踏岚发现,每次螳螂人只会选择长城上的一个基地进行猛烈的攻击,所以,祝踏岚每次都要从影踪禅院赶到被攻击的基地亲临前线指挥战斗。但是,在长城上移动是很耗时的,为了能更快的赶到任何一个可能被攻击的基地,祝踏岚决定修建一对传送门。
    一对传送门由两个入口组成,它能实现在两个入口间的瞬间转移。出于安全考虑,这两个入口一定要建造在基地上。祝踏岚想选出两个合适的基地建造这一对传送门,使得他从影踪禅院赶到任何一个基地所需要的移动距离最远的那个最短。(每次祝踏岚都会选择采用最短的方式前往每一个基地)。你能帮助他么?


Input

第一行为一个正整数T,表示测试数据组数。

每组测试数据第一行为一个整数N(1 <= N <= 100000),第二行包含N-1个正整数,其中第i个数表示编号为i的基地与编号为i+1的基地之间的长城长度。此长度不会超过2147483647.

Output

对每组测试数据输出一行,仅含一个整数,表示按照最优方案建造完虫洞后,祝踏岚需要从基地1赶到的移动距离最远的基地的移动距离。

Sample Input

2

3

1 20

6

1 2 3 4 5
Sample Output

1

5
Source
2016级新生程序设计全国邀请赛

思路:


1、部分思路参考自:http://www.cnblogs.com/xingkongyihao/p/6105717.html....


2、首先我们这么想,建造传送阵的意义是什么?明显是为了缩减从起点到最远点的距离。

紧接着,还能够缩减从起点到其他各个点的距离。

那么我们如果将这个传送阵放到距离起点X远处,那么我们从起点到传送门再到其他各个点就有一个起步长度。很显然我们希望没有这个起步长度。那么想到,将第一个传送阵放到原点(出发点。)


3、接下来我们就可以O(n)枚举第二个传送阵的点,那么接下来考虑此时最短路最长可能的情况:
①从传送阵到最后一个点的长度。

②从起点到的一个点Z

③以及这个点Z到第二个传送阵的距离。

那么我们考虑如何维护②和③....(暴力处理时间复杂度会达到O(n^2)......好鸡肋啊,下边这句话想到了就不至于卡了俩小时啦T T)

我们很明显想要将这两个长度使其尽可能的接近。那么我们维护一个变量j,使得其保证sum【j】>sum【i】-sum【j】&&sum【j-1】<=sum【i】-sum【j-1】;

那么这个点j就是上述过程中的点Z.


Ac代码:


#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define ll long long int
ll a[100050];
ll sum[100050];
ll ans;
int n;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        memset(sum,0,sizeof(sum));
        for(int i=2;i<=n;i++)scanf("%lld",&a[i]);
        for(int i=2;i<=n;i++)sum[i]=sum[i-1]+a[i];
        ans=600000000000000000;
        ll tmp=0;
        int j=1;
        for(int i=1;i<=n;i++)
        {
            while(j<i&&sum[j]<=sum[i]-sum[j])
            {
                j++;
            }
            tmp=max(sum[i]-sum[j],sum[j-1]);
            tmp=max(sum[n]-sum[i],tmp);
            if(tmp<ans)
            {
                ans=tmp;
            }
        }
        printf("%lld\n",ans);
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值