首页 > 其他 > 详细

Berry Jam (前缀和)cf教育场

时间:2019-12-20 16:07:59      阅读:145      评论:0      收藏:0      [点我收藏+]

距离上一篇博客又2个月了 寻思着该除除草了

教育场是真的好难 可能是因为我还是只菜鸡 哭唧唧

 

先说下题意:有2*n罐果酱,草莓和蓝莓,梯子在中间从梯子那开始往两边吃(可以一会左一会右),问最少吃多少果酱可以使两种酱剩下的数量相等。

一开始没写出来,看了大佬的做法才会的。(因为下午刚考完拉链法冲突处理脑海里都是他ing,然后发现想复杂了.....

题解:先将为2的改成-1。梯子右边从最右边开始求前缀和(前边所有果酱中两种果酱的差),记录前缀和的下标在数组c中(这个地方可能会有前缀和是一样的,那当然是让他越靠左越好了,这样没被吃的就越多了,所以从右边开始求前缀和),因为可能会有负数,所以前缀和加上100000存储。梯子左边从左求前缀和sum,然后右边界r--,比较求出n-r+c[-sum+100000]。也就是让左边少多少个那种酱,右边就得多多少个。

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int INF=0x3f3f3f;
 5 const int maxn=100100;
 6 int a[maxn],b[maxn],c[maxn*2],d[maxn];
 7 
 8 int main()
 9 {
10     int t;
11     scanf("%d",&t);
12     while(t--){
13         int n;
14         scanf("%d",&n);
15         for(int i=0;i<n;i++){
16             scanf("%d",&a[i]);
17             if(a[i]!=1) a[i]=-1;
18         }
19         for(int i=0;i<n;i++){
20             scanf("%d",&b[i]);
21             if(b[i]!=1) b[i]=-1;
22         }
23         for(int i=0;i<200100;i++)
24             c[i]=INF;
25         c[100000]=n;
26         d[n]=0;
27         for(int i=n-1;i>=0;i--)
28             d[i]=d[i+1]+b[i],c[d[i]+100000]=i;
29         int sum=0;
30         int ans=INF;
31         for(int i=0;i<n;i++)
32             sum+=a[i];
33         ans=min(ans,c[-sum+100000]);
34         for(int i=n-1;i>=0;i--){
35             sum-=a[i];
36             ans=min(ans,n-i+c[-sum+100000]);
37         }
38         printf("%d\n",ans);
39     }
40     return 0;
41 }

Berry Jam (前缀和)cf教育场

原文:https://www.cnblogs.com/lilibuxiangtle/p/12073372.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!