165C.Another Problem on Strings

codeforces百题计划第一周(4)

观察

发现对于k!=0时,对于包含k个1的区间,第一个1左边的0和第k个1右边的0时可选可不选的,那么对于包含当前k个1的区间,找到包含最有0的所有不同情况就时对于包含当前k个1的所有区间

记录每个1的位置,cnt[i]

每个1左右0的个数,l[i],r[i]

对于每个包含k个1的区间就是 (r[i]+1)*(l[i-k+1]+1)

这种题就不要怕麻烦,怕麻烦是写不出来的,硬刚就对了

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn=1e6+5;
 5 typedef long long ll;
 6 const ll INF=1e18;
 7 ll c[maxn];
 8 ll l[maxn];
 9 ll r[maxn];
10 ll C(int kk)
11 {
12     ll res=1;
13         for(int i=kk;i>=1;i--)
14         {
15             res=kk*res;
16         }
17     return res;
18 } 
19 int main()
20 {
21     int k;cin>>k;
22     string str;cin>>str;
23     
24     if(k==0)
25     {
26         ll s=0;ll res=0;
27         for(int i=0;i<str.size();i++)
28         {
29             if(str[i]=='0') s++;
30          
31         else
32         {
33             res+=(s*(s+1)/2);
34             s=0;
35         }
36     }
37         res+=(s*(s+1)/2);
38         cout <<res<<endl;
39         return 0;
40     }
41     
42     int ct=0;int cnt=0;
43     for(int i=0;i<str.size();i++){
44         if(str[i]=='0') ct++;         
45         else if(str[i]=='1') 
46         {
47             r[cnt]=ct;
48             c[++cnt]=i;
49             l[cnt]=ct;
50             ct=0;
51         }
52     }    
53     r[cnt]=ct;
54     ll ans=0;
55     /*for(int i=1;i<=cnt;i++)
56     {
57         cout <<c[i]<<" "<<l[i]<<" "<<r[i]<<endl;
58     }*/
59     for(int i=k;i<=cnt;i++)
60     {
61         ans+=(r[i]+1)*(l[i-k+1]+1);
62     }
63     cout <<ans<<endl;
64     return 0;
65 } 
66 
67 //记录每个1的位置,然后从cnt==k开始,再记录每个1左右有几个0,那么就是右*左 

 

posted @ 2019-08-06 13:03  Chuhanjing  阅读(140)  评论(0编辑  收藏  举报