丢手绢(双指针)

       丢手绢

题目描述 

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

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

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

输入描述:

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

输出描述:

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

示例1

输入

3
1
2
3

输出

3

备注:

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

思路:

用双指针模拟区间,求最大就近距离

代码:

#include<bits/stdc++.h>
using namespace std;
int a[100005];
int main(){
    int n;cin>>n;
    int mix=0;
    int sum=0;
    for(int i=1;i<=n;++i){
        cin>>a[i];
        sum+=a[i];//总距离
    }
    int r=0,to=sum/2,x=0;//右端点,人与人的最大距离为周长/2,人与人的距离
    for(int i=1;i<=n;++i){//左端点
        while(x<to){//小于最大距离
            x+=a[(r++)%(n+1)];//一直加
        }
        mix=max(mix,min(x,sum-x));//由于是最大的就近距离,所以开个min求,然后max
        x-=a[i];//左端点即将转移,减去这个值
    }
    cout<<mix;
}

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个约瑟夫问题的解法,约瑟夫问题是一个经典的数学问题,也称为手绢问题。 这段代码实现了约瑟夫问题的解法,具体来说,它实现了以下几个功能: 1.定义了一个结构体Node,表示链表中的节点,包含两个成员变量:data表示节点的编号,passage表示节点的密码。 2.定义了一个函数Creatlink,用于创建一个循环链表。这个函数的参数包括n(表示节点个数)、phead(表示链表头节点指针)和lflag(表示链表尾节点指针)。函数首先初始化头节点的data为1,然后依次输入n个节点的密码,并将它们加入链表中。最后将尾节点指向头节点,并返回尾节点指针。 3.定义了一个函数printlink,用于打印出最终的报数顺序。这个函数的参数包括m(表示起始密码)、n(表示节点个数)、phead(表示链表头节点指针)和lflag(表示链表尾节点指针)。函数首先确定起始节点,然后依次报数,将每个报数的节点从链表中删除,并打印出其编号。直到链表中只剩下一个节点为止。 4.在main函数中,首先输入m和n的值,然后调用Creatlink函数创建循环链表,最后调用printlink函数打印出最终的报数顺序。 总体来说,这段代码实现了约瑟夫问题的解法,它使用了循环链表来模拟人们围成的圆圈,每次从起始位置开始报数,报数到m的人被淘汰,然后从下一个人开始重新报数,直到最后只剩下一个人为止。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值