题目描述
“丢、丢、丢手绢,轻轻地放在小朋友的后面,大家不要告诉她,快点快点抓住她,快点快点抓住她。”
牛客幼儿园的小朋友们围成了一个圆圈准备玩丢手绢的游戏,但是小朋友们太小了,不能围成一个均匀的圆圈,即每个小朋友的间隔可能会不一致。为了大家能够愉快的玩耍,我们需要知道离得最远的两个小朋友离得有多远(如果太远的话牛老师就要来帮忙调整队形啦!)。
因为是玩丢手绢,所以小朋友只能沿着圆圈外围跑,所以我们定义两个小朋友的距离为沿着圆圈顺时针走或者逆时针走的最近距离。
输入描述:
第一行一个整数N,表示有N个小朋友玩丢手绢的游戏。
接下来的第2到第n行,第i行有一个整数,表示第i-1个小朋友顺时针到第i个小朋友的距离。
最后一行是第N个小朋友顺时针到第一个小朋友的距离。
输出描述:
输出一个整数,为离得最远的两个小朋友的距离。
输入:
3
1
2
3
输出:
3
思路:算法核心:尺取法
ps:第一眼前缀和,用前缀和想了半天,循环数组不好解决。
最远距离不超过圆周长的一半,所以当跑在前面的小朋友跑过周长一半时候,再跑,两者距离只会减小,没有意义了,应该停下来,后面追的小朋友向前走一步,代码有详注。
#include <bits/stdc++.h>
using namespace std;
int arr[100005];//距离
int main()
{
int i,n,j,maxn,sum=0,len=0,flag=0,cnt=0;
cin>>n;//输入
for(i=0;i<n;i++) {cin>>arr[i];sum+=arr[i];}//记录和,求一半
int p=0,half=sum/2;//p为后面追的小朋友
for(i=0;i<=n;i++,i%=n)
{
len+=arr[i];
if(len==half) {maxn=half;break;}//如果距离到周长一半直接输出了
while((len>half&&p<=i)||(len>half&&p<=i+n-1))//超过一半时,第二个情况是求第1和第N个小朋友
{
if(!flag) maxn=len-arr[i];//先找到第一次满足要求的距离
flag=1;
len-=arr[p%n];//后指针向前移动
p++;
}
maxn=max(maxn,min(len,sum-len));//方便计算直接取len和圆周长减去len的最小值,肯定比周长一半小
if(maxn==half) break;//如果距离是周长一半就输出
if(i==0) cnt++;//计算第1和第N个小朋友间距离时的情况
if(cnt==2) break;
}
cout<<maxn<<endl;
}