传送门

 

参考资料:

  [1]:http://www.voidcn.com/article/p-huucvank-dv.html

题意:

  题意就是找一个连续的子区间,使它的和的绝对值最接近target。

题解:

  这题的做法是先预处理出前缀和,然后对前缀和进行排序,再用尺取法贪心的去找最合适的区间。

  要注意的是尺取法时首尾指针一定不能相同,因为这时区间相减结果为0,但实际上区间为空,这是不存在的,可能会产生错误的结果。

  处理时,把(0,0)这个点也放进数组一起排序,比单独判断起点为1的区间更方便。

  还有ans初始化的值INF一定要大于t的最大值。

  最后说说这个题最重要的突破口,对前缀和排序。为什么这么做是对的呢?

  因为这题是取区间的和的绝对值,所以所以用sum[r]-sum[l] 和 sum[l]-sum[r]是没有区别的。

  这样排序后,把原来无序的前缀和变成有序的了,就便于枚举的处理,并且不影响最终结果。

  以上分析来自参考资料[1]。

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 #define P pair<int ,int >
 6 const int maxn=1e5+10;
 7 
 8 int n,k;
 9 P p[maxn];
10 
11 bool cmp(P _a,P _b){
12     return _a.second < _b.second;
13 }
14 void Solve(int t)
15 {
16     int l=0,r=1;
17     int resL=p[l].first,resR=p[r].first;//先假设区间[1,p[1].first]为解
18     int resSum=p[r].second-p[l].second;
19     while(r <= n)
20     {
21         int curSum=p[r].second-p[l].second;
22         if(abs(curSum-t) < abs(resSum-t))//判断是否可以更新 resSum
23         {
24             resSum=curSum;
25             resL=p[l].first;
26             resR=p[r].first;
27         }
28         if(curSum < t)//如果当前区间值过小,增大当前值
29             r++;
30         else if(curSum > t)//如果当前区间值过大,减小当前值
31             l++;
32         else
33             break;
34         if(l == r)
35             r++;
36     }
37     if(resL > resR)
38         swap(resL,resR);
39     printf("%d %d %d\n",resSum,resL+1,resR);//while()循环中做区间减法时始终左边界一直被减掉
40 }
41 int main()
42 {
43 //    freopen("C:\\Users\\lenovo\\Desktop\\in.txt\\poj2566.txt","r",stdin);
44     while(~scanf("%d%d",&n,&k),n != 0 || k != 0)
45     {
46         int sum=0;
47         for(int i=1;i <= n;++i)
48         {
49             int val;
50             scanf("%d",&val);
51             sum += val;
52             p[i]=P(i,sum);
53         }
54         p[0]=P(0,0);
55         sort(p,p+n+1,cmp);
56         while(k--)
57         {
58             int t;
59             scanf("%d",&t);
60             Solve(t);
61         }
62     }
63     return 0;
64 }
View Code

相关文章:

  • 2021-09-21
  • 2021-09-28
  • 2021-06-23
  • 2022-02-16
  • 2022-12-23
  • 2021-04-19
  • 2021-09-14
  • 2022-02-01
猜你喜欢
  • 2021-03-31
  • 2022-12-23
  • 2021-12-23
  • 2022-02-19
  • 2021-07-15
  • 2021-11-29
  • 2021-08-02
相关资源
相似解决方案