您的位置:首页 > 其它

[NOIP模拟赛][并没有用二分][乱搞AC]

2016-10-17 17:29 260 查看

圆圈舞蹈

[问题描述]

熊大妈的奶牛在时针的带领下,围成了一个圆圈跳舞。由于没有严格的教育,奶牛们之间的间隔不一致。

奶牛想知道两只最远的奶牛到底隔了多远。奶牛A到B的距离为A顺时针走和逆时针走,到达B的较短路程。告诉你相邻两个奶牛间的距离,请你告诉奶牛两只最远的奶牛到底隔了多远。

[输入]

第一行一个整数N,表示有N只奶牛。(2<=N<=100000)

接下来2~N+1行,第i行有一个数,表示第i-1头奶牛顺时针到第i头奶牛的距离。

(1<=距离<=maxlongint,距离和<=maxlongint)

第N+1行的数表示第N头奶牛顺时针到第1头奶牛的距离。

[输出]

一行,表示最大距离

[样例]

circle.in

5

1

2

3

4

5

circle.out

7

[样例解析]

Circle.out所有奶牛i到j之间的距离和到达方式(顺为顺时针,逆为逆时针)如下:

1

2

3

4

5

1

0

1(顺)

3(顺)

6(顺)

5(逆)

2

1(逆)

0

2(顺)

5(顺)

6(逆)

3

3(逆)

2(逆)

0

3(顺)

7(顺)

4

6(逆)

5(逆)

3(逆)

0

4(顺)

5

5(顺)

6(顺)

7(逆)

4(逆)

0

[Solution]

  这道题网上全是二分做的,复杂度差不多都是O(nlogn)。但是这道题乱搞可以搞到O(n)之间。

  首先处理一遍前缀和。定义左右端点都为1,然后不断右移右端点,max_len=max(max_len,sum[R]-sum[L]),直到左右端点间距大于环长的一半。当间距大于环长的一半时,将左端点右移缩小区间,max_len=max(max_len,tot-(sum[R]-sum[L])),直到左端点到右端点的间距不大于环长的一半。这样最后得到的max_len就是答案。

  贴AC代码:

#include <cstdio>
#include <algorithm>
using namespace std;
int N,L=1,R=1;
long long int tot,max_len=0;
long long int data[100010],sum[100010],save[100010];
int main(){
scanf("%d",&N);
for(int i=1;i<=N;++i) scanf("%lld",&data[i]),tot+=data[i],sum[i]=sum[i-1]+data[i];
while(L<=R&&R<=N){
long long int d=sum[R]-sum[L];
if(d<=tot/2) {++R; max_len=max(max_len,d);}
else {++L; max_len=max(max_len,tot-d);}
}
printf("%lld",max_len);
return 0;
}


  二分须谨慎,暴力保平安。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: