塔神酷爱玩梦幻西游这款游戏,这款游戏以著名的章回小说《西游记》故事为背景,透过Q版的人物,营造出浪漫的网络游戏风格.塔神以追求天下无敌为目标,从一个默默无闻的菜鸟,打拼到了登峰造极的大师,犀利的人物当然离不开犀利的装备,于是塔神带着一堆票子开始逛市场买装备,塔神为了图个方便,只会在连续的几家摊位买装备.
现在市场有n个摊位,其中不乏奸商把价格抬的很高,但是对于混了这么就江湖的塔神来说,对每件装备心中当然会有个固定的价格,所以逛完市场以后,他把每家装备的价钱与自己心中的价钱的差价列成了一张表,只要这些连续差价的和的绝对值最小,塔神就会高兴的hold不住了,于是他把问题丢给可怜的zzd,但是像zzd这种菜鸟解决不了塔神提出高端的问题,你能帮助他完成任务吗?
输入
第一行输入n(n<=100000)表示n个摊位,以0结束
第二行包括n个数据,第i个数据m表示第i家摊位装备的差价(-100<=m<=100)
输出
输出让塔神能满意的最小值
样例输入
2
-10 4
6
2 -4 -2 6 1 5
4
1 2 -4 -5
0
样例输出
4
0
1
题意
连续子段和绝对值最小。
题解
一开始以为要O(n),然后记得求连续子段和最大的那个贪心,就想魔改,改了半天放弃了。
记一个前缀和sum[i]=a[1...i],题目变成找(i,j),求|sum[i]-sum[j]|最小值。
那么把sum排个序,求相邻最小就行了。
复杂度O(nlogn)。
代码
#include<bits/stdc++.h>
using namespace std; const int N=1e5+; int sum[N];
int main()
{
int n,x;
while(scanf("%d",&n)!=EOF,n)
{
for(int i=;i<=n;i++)
{
scanf("%d",&x);
sum[i]=sum[i-]+x;
}
sort(sum,sum++n);
int ans=1e9;
for(int i=;i<=n;i++)ans=min(ans,abs(sum[i]-sum[i-]));
printf("%d\n",ans);
}
return ;
}