题目链接:https://cn.vjudge.net/contest/268424#problem/H
参考来源:https://blog.csdn.net/chen_zan_yu_/article/details/83904832
https://blog.csdn.net/BePosit/article/details/83927964
题目描述:
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:
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 binary 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).
题目大意:
给定两个0,1串,有两次操作机会,第一次操作第一个串,第二次操作第二个串。
选定一个连续区间把这里面的数字翻转,问有多少种方案使得两串相同。
思路:
只要分4种情况即可
1,最初全都相同,那么两次操作必须选择相同位置进行操作才符合要求
2.有一段连续区间不同的,这时两次操作可以把这一段区间让这两次操作分配一下,但是一定要保证
它们两个不重叠且恰好覆盖这段不同的区间,一种分配情况为1——>到区间长度-1因为不能交叉,
它们只能选择分配不同的区间那么情况数就是 :区间长度-1,还可以它们其中一个全部选择这些不同的
搭配上原来相同的的字符,每一次这种搭配只能是向(不同区间)的一侧,情况又是两端相同字符长度
然后这些情况它们俩都可以交换操作所以情况数*2得出:
sum=2*(两侧相同的个数:(x1+n-1-y2)+不同区间的长度:(y2-x1));
或直接为sum=2*(n-1)
3.有两段连续区间不同,那么他们可以有三种选择,然后两个人不同加倍则为6种选择
4.大于两段连续不同的区间,这样他们没有可选择的余地了。
代码:
#include
#include
#include
using namespace std;
const long long int maxn=1000010;
int main()
{
int T,n;
char a[maxn],b[maxn];
while(scanf("%d",&T)!=EOF)
{
for(int k=0;k1)||(cnt
敲这道题时就在想,写完一定要好好吐槽一下,我天呀,一下午呀,都在弄这道题。看懂了题之后就在那想思路,边敲边完善,不断地调整自己的代码,最后终于对题目有了清晰地理解,却难在了代码上,参考了了大佬的代码,才觉着自己的代码如此麻烦,过程中,自己一直在思考的是,先看相同段与不同段一共有多少段,只有不同段为1和2时才有可能得到解,多于2一定是不对的。然后自己就在尝试如何判断得到的是1个不同段还是两个不同段,结果总是不对,但是上方的那段正确的代码中却巧妙地解决了这个问题。