2019牛客暑期多校训练营(第三场) B Crazy Binary String(前缀和)

将'0'看成-1,'1'看成1,记录前缀和,用一个桶记录当前前缀和最小出现的下标,之后再次出现该值,说明这段长度中0,1的数量相等。

AC代码:

语言:C++ 代码长度:1394 运行时间: 4 ms 占用内存:1244K 

 1 #include<bits/stdc++.h>
 2 #define numm ch-48
 3 #define pd putchar(' ')
 4 #define pn putchar('
')
 5 #define pb push_back
 6 #define mp make_pair
 7 #define fi first
 8 #define se second
 9 #define fi first
10 #define se second
11 #define fre1 freopen("1.txt","r",stdin)
12 #define fre2 freopen("2.txt","w",stdout)
13 using namespace std;
14 template <typename T>
15 void read(T &res) {
16     bool flag=false;char ch;
17     while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
18     for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
19     flag&&(res=-res);
20 }
21 template <typename T>
22 void write(T x) {
23     if(x<0) putchar('-'),x=-x;
24     if(x>9) write(x/10);
25     putchar(x%10+'0');
26 }
27 const int maxn=200010;
28 typedef long long ll;
29 typedef long double ld;
30 const ll mod=1e9+7;
31 char s[maxn>>1];
32 int sum[maxn>>1];
33 int t[maxn];
34 int main()
35 {
36     int n;
37     read(n);
38     scanf("%s",s);
39     int len=strlen(s);
40  
41     int min1=0,min0=0,ans2;
42     for(int i=0;i<len;i++)
43         if(s[i]=='1') sum[i]++,min1++;
44         else sum[i]--,min0++;
45     ans2=min(min0,min1)*2;
46  
47     for(int i=1;i<len;i++)
48         sum[i]+=sum[i-1];
49 //    for(int i=0;i<len;i++)
50 //        write(sum[i]),pd;
51 //    pn;
52     int ans1=0;
53     t[100000]=0;
54     for(int i=0;i<len;i++) {
55         int d=sum[i]+100000;
56         if(d==100000) ans1=max(i+1,ans1);
57         else if(t[d]) ans1=max(i-t[d]+1,ans1);
58         else t[d]=i+1;
59     }
60     write(ans1),pd,write(ans2);
61     return 0;
62 }
View Code
原文地址:https://www.cnblogs.com/wuliking/p/11253058.html