您的位置:首页 > 其它

最小和[CODEVS1635]解题报告

2014-11-05 16:44 309 查看
题面:输出长度为N的数列中区间和绝对值最小的绝对值,若有多个最小区间和绝对值,则输出其可能的最长长度。N<=10^5

思路:把区间转换成前缀和,区间绝对值最小其实就是前缀和之差的绝对值最小,所以我们将其排序即可,相差最小的区间一定出现在排序后相邻的两个前缀和之中。

但是还要注意一些问题:

①若有多个区间的值相同,则应将他们再按端点排序,然后选择端点相差最大的两个。

②循环边界和更新条件需要仔细揣摩。

但是吧。。虽然上面两条我都没有考虑到,但还是A了这道题。。所有正确的点,9个点。。

至于还有一个点。。这个题的数据应该是有问题,我把数据下下来暴力做了一遍,也跟“正确答案”不一样。

代码:

#include<iostream>

using namespace std;

#include<cstdio>

#include<string>

#include<cmath>

#include<algorithm>

typedef long long lld;

lld a[100001];

struct S{

lld s;

int i;

bool operator < (S a) const{

if(s!=a.s)return s<a.s;

else return i<a.i;

}

}s[100002];

int main(){

int ansl,tmpl,i,N,j;

lld anss=0x7fffffffffffffffLL,tmps;

scanf("%d",&N);

s[0]=(S){0,0};

for(i=1,++N;i<N;++i){

scanf("%I64d",a+i);

s[i].s=s[i-1].s+a[i];

s[i].i=i;

}

sort(s,s+N);

s
.s=1LL<<62;

for(i=0,--N;i<N;++i){

if(s[i].s==s[i+1].s){

if(anss){

anss=0;

ansl=0;

}

j=i;

while(s[i].s==s[i+1].s)++i;

ansl=max(abs(s[i].i-s[j].i),ansl);

}

tmps=abs(s[i].s-s[i+1].s);

tmpl=abs(s[i].i-s[i+1].i);

if(tmps<anss||tmps==anss&&tmpl>ansl){

anss=tmps;

ansl=tmpl;

}

}

cout<<anss<<endl<<ansl;

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