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('\n') 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 }
所谓人生,一半惊喜,一半遗憾