题目来源:ZOJ
4060 Flippy Sequence
DreamGrid has just found two binary sequences and ( for all ) from his virtual machine! He would like to perform the operation described below exactly twice, so that holds for all after the two operations.
The operation is: Select two integers and (), change to for all .
DreamGrid would like to know the number of ways to do so.
We use the following rules to determine whether two ways are different:
- Let , where , be a valid operation pair denoting that DreamGrid selects integers and for the first operation and integers and for the second operation;
- Let , where , be another valid operation pair denoting that DreamGrid selects integers and for the first operation and integers and for the second operation.
- and are considered different, if there exists an integer () such that .
Input
There are multiple test cases. The first line of the input contains an integer , indicating the number of test cases. For each test case:
The first line contains an integer (), indicating the length of two b
inary sequences.
The second line contains a string () of length , indicating the first binary sequence.
The third line contains a string () of length , indicating the second binary sequence.
It's guaranteed that the sum of in all test cases will not exceed .
Output
For each test case, output an integer denoting the answer.
Sample Input
3 1 1 0 2 00 11 5 01010 00111
Sample Output
0 2 6
Hint
For the second sample test case, there are two valid operation pairs: (1, 1, 2, 2) and (2, 2, 1, 1).
For the third sample test case, there are six valid operation pairs: (2, 3, 5, 5), (5, 5, 2, 3), (2, 5, 4, 4), (4, 4, 2, 5), (2, 4, 4, 5) and (4, 5, 2, 4).
题目大意:
给出2个长度为n的01串s和t,对s进行两次操作,每次操作选择s串的一段区间,将区间内的数字0变成1,1变成0,问将s变为t一共有多少种方法
题解:
先统计一下s和t有几段不相同的区间num
①num>=3,无解,没法s经过两次从操作变为t,方法数为0
②num=2,固定为6种
③num=1,
可以先反转a+b,再反转a;先反转b+c,再反转c;b内部分成两半反转
④num=0,即全都相同,这时候就可以把整个串分为两半反转,方法数为?
#include<cstdio>
#include<cstring>
#define ll long long
#include<vector>
using namespace std;
char s1[1000010],s2[1000010];
int main()
{
int T;
scanf("%d",&T);
int n;
while(T--){
scanf("%d",&n) ;
scanf("%s",s1) ;
scanf("%s",s2) ;
int i=0;
vector <pair <int ,int> > seg;
int pre=-1;
while(i<n){
pre=i;
if(s1[i]!=s2[i]){
while(s1[i]!=s2[i]&&i<n){
++i;
}
if(i<n||(i==n&&s1[n-1]!=s2[i-1]))
seg.push_back(make_pair(pre,i));
}
++i;
}
int num=seg.size();
ll ans =0;
if(num>=3 ) ans=0;
else if(num==2) ans=6;
else if(num==1) ans=2*(seg[0].first+(n-seg[0].second)+seg[0].second-seg[0].first-1) ;
else ans=(ll) n*(n+1)/2;
printf("%lld\n" ,ans) ;
}
}