丢手绢「掘金日新计划 · 12 月更文挑战」

125 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第22天,点击查看活动详情

丢手绢

链接:ac.nowcoder.com/acm/problem…
来源:牛客网

题目描述

“丢~ 丢~ 丢手绢,轻轻地放在小朋友的后面,大家不要告诉她,快点快点抓住她,快点快点抓住她。”

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

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

输入描述:

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

输出描述:

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

示例1

输入

3
1
2
3

输出

3

备注:

2≤N≤100000
距离和(圆圈周长)小于等于2147483647

思路

这道题认真思考之后,决定用尺取法来写。用左右指针来分别记录。首先右指针右移扩大距离,当距离大于周长的一半之后,就要更新当前的距离和之前的记录哪个距离更远。右指针右移超过边界,所以考虑用取模来防止越界。

代码

#include<bits/stdc++.h>
using namespace std;
int a[100010];
int main()
{
    int n;
    cin>>n;
    int sum=0;
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    int mid=sum/2;
    int cnt=0;
    int res=0;
    for(int i=0,j=0;i<n;i++){
        while(cnt<mid){
            cnt+=a[(j++)%n];
        }
        res=max(res,min(cnt,sum-cnt));
        cnt-=a[i];
    }
    cout<<res;
    return 0;
}