Another Problem on Strings CodeForces - 165C

原题链接

考察:前缀和+二分+双指针

补一个大佬的神级解法 Go

错误思路:

      纯双指针处理,写了几个小时没写出来.....

思路:

       前缀和预处理,sum[i]表示1~i坐标有多少个1,那么[l,r]区间内1的个数为sum[r] - sum[l-1],那么我们可以枚举端点,计算[l,r]区间里有多少个1,如果==k,ans++.

       以上为暴力思路,根据数据我们还需要优化.一般优化第二层循环.枚举左端点,找到==sum[i]+k的sum[j]和>sum[i]+k的sum[r],[j,r)之间都为答案.

       但是要特判k = 0,这里本蒟蒻用的双指针处理.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 const int N = 1000010;
 8 int k,sum[N];
 9 char s[N];
10 LL ans;
11 int main()
12 {
13     scanf("%d%s",&k,s+1);
14     int len = strlen(s+1),cnt = 0;
15     for(int i=1;i<=len;i++) sum[i] = sum[i-1]+(s[i]-'0');
16     if(!k)
17     {
18         for(int i=1,j=1;i<=len;i++)
19         {
20             int t = s[i]-'0';
21             if(t) continue;
22             if(j<i) j = i;
23             while(j<=len&&s[j]=='0') j++;
24             ans+=(LL)(j-i);
25         }
26         printf("%I64d\n",ans);
27         return 0; 
28     }
29     for(int i=0;i<len;i++)
30     {//sum[l~r]-sum[i] = k
31         int l = lower_bound(sum+1,sum+len+1,sum[i]+k)-sum;
32         int r = upper_bound(sum+1,sum+len+1,sum[i]+k)-sum;
33         if(l==len+1) break;//当l==len+1,r一定==len+1,r-l==0; 
34         ans+=(LL)(r-l);
35     }
36     printf("%I64d\n",ans);
37     return 0;
38 }

 

posted @ 2021-03-25 23:21  acmloser  阅读(30)  评论(0编辑  收藏  举报