丢手绢——尺取法

题目描述

丢~丢~丢手绢,轻轻地放在小朋友的后面,大家不要告诉她,快点快点抓住她,快点快点抓住她。”
牛客幼儿园的小朋友们围成了一个圆圈准备玩丢手绢的游戏,但是小朋友们太小了,不能围成一个均匀的圆圈,即每个小朋友的间隔可能会不一致。为了大家能够愉快的玩耍,我们需要知道离得最远的两个小朋友离得有多(如果太远的话牛老师就要来帮忙调整队形啦!)。

因为是玩丢手绢,所以小朋友只能沿着圆圈外围跑,所以我们定义两个小朋友的距离为沿着圆圈顺时针走或者逆时针走的最近距离。

输入描述

第一行一个整数N,表示有N个小朋友玩丢手绢的游戏。
接下来的第2到第n行,第i行有一个整数,表示第i-1个小朋友顺时针到第i个小朋友的距离。
最后一行是第N个小朋友顺时针到第一个小朋友的距离。

输出描述

输出一个整数,为离得最远的两个小朋友的距离。

示例1

输入

3

1 2 3

输出

3

备注

2≤N≤100000

距离和(圆圈周长)小于等于2147483647

思路

  • 定义两个变量,begin表示的是第一个小朋友,end表示的是第二个小朋友,begin~end是两个小朋友的距离, res维护两个小朋友的最大距离, sum维护begin~end的距离
  • 首先,begin不动,end顺时针移动,每遍历到一个小朋友,将当前距离和res取最大值,直到两个小朋友的距离大于整个圆圈距离的一半,这个时候以begin为第一个小朋友的最大距离就找到了
  • 将begin向顺时针移动一位,sum减去移动的距离,也就是begin~begin+1的距离,end再顺时针移动,找到两个小朋友大于整个圆圈距离的一半
  • begin遍历每一个小朋友,也就是将每个小朋友作为第一个,比较最大的距离

代码实现

#include <iostream>

using namespace std;

const int N = 1e5 + 10;
int n;
int a[N];	// 表示第当前小朋友距离上一个小朋友的距离,下标0表示第二个小朋友距离第一个小朋友的距离

int main()
{
    cin >> n;
    int len = 0;	// 整个圆圈的总距离
    for(int i = 0;i < n; i++)
    {
        cin >> a[i];
        len += a[i];
    }
    int begin = 0,end = 0, sum = 0, res = 0;
    while(begin < n)	// 以每一个小朋友作为第一个
    {
        if(sum <= len / 2)	// 以begin为第一个小朋友的方案结束
        {
            res = max(res, sum);	// 维护最大距离
            sum += a[end++];
            end = end % n;	// 将end维护在0~n-1区间内
        }
        else
        {
            sum -= a[begin++];	// 第一个小朋友向顺时针移动一位
        }
    }
    
    cout << res << endl;
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值