题目:传送门
思路:
1. 对于s[i] = t[i] 我们不需要处理,那么去掉s[i] = t[i]后,我们能够处理的子序列必定是 10101010... 或 01010101... ; 如果是 s' = 1100 , t' = 0011 显然不能。
2. 那么我们得出这一条结论了,这道题的做法就类似于括号匹配,可以直接模拟,删除相同的(s[i]=t[i]),也可以写的更简洁一些(类似于差分的思想)
代码:
#include<bits/stdc++.h> /* #include<cstdio> #include<cmath> #include<cstring> #include<vector> #include<cctype> #include<queue> #include<algorithm> #include<map> #include<set> */ #pragma GCC optimize(2) using namespace std; typedef long long LL; typedef pair<int,int> pii; typedef pair<double,double> pdd; const int N=1e6+5; const int M=1e4+5; const int inf=0x3f3f3f3f; const LL mod=1e9+7; const double eps=1e-9; const long double pi=acos(-1.0L); #define ls (i<<1) #define rs (i<<1|1) #define fi first #define se second #define pb push_back #define mk make_pair #define mem(a,b) memset(a,b,sizeof(a)) LL read() { LL x=0,t=1; char ch; while(!isdigit(ch=getchar())) if(ch=='-') t=-1; while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } return x*t; } char s[N],t[N]; int main() { int T=1; while(T--) { int n=read(); scanf("%s%s",s+1,t+1); //写法1 int t0=0,t1=0,de=0; for(int i=1;i<=n;i++) { if(s[i]==t[i]) continue; if(s[i]>t[i]) { t1++; de++;//de 用来判断01个数是否相等 if(t0) t0--;//如果t0==0 ,那么就相当于创建了一条以1为开头的子序列 } else { t0++; de--; if(t1) t1--; //如果 t1==0 , 那么就相当于创建了一条以0为开头的子序列 } } if(de) printf("-1 "); else printf("%d ",t1+t0); //写法2 int ma=0,mi=0,sum=0; for(int i=1;i<=n;i++)//0会和之前多余的1配对,1会和之前多余的0配对; { sum+=s[i]-t[i]; ma=max(ma,sum); mi=min(mi,sum); } if(sum) printf("-1 "); else printf("%d ",ma-mi); } }