Prefix Flip (Hard Version)

思路:

将a串都变成0000,再将000变成b串

重点:

遍历a串,当遍历到a[i]是字符1时,说明前面的i-1都是0,所以可以对之前i-1直接进行取反在逆转,无影响都变为1

在操作这i个字符,取反在逆转都变成0000。

逆序遍历b串,当遍历到b[i]是1时,需要将此时全0串的第i位变成1,即对全0串的这i个字符取反在逆转,都变成1

在操作i-1个字符,取反再逆转又变成0,即成为b串的000001。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include <bitset>
#include<set>
#include<map>
#include<unordered_map>
#include<vector>
#include<cmath>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int, int> p;
#define pb push_back
int t, n;
char a[200009], b[200009];
vector<int>vec, s;
int main(){
    cin >> t;
    while (t--){
        vec.clear(); s.clear();
        cin >> n >> (a + 1) >> (b + 1);
        int flag = 0;
        //若是ab相同则输出0结束
        for (int i = 1; i <= n; i++)
            if (a[i] != b[i])    flag = 1;
        if (flag == 0){
            cout << 0 << endl;
            continue;
        }
        //将a串全部变成0 当a[x]不是0时,令[1,x−1]的数先变成1,[1,x]的数都变成0
        if (a[1] == '1')    vec.pb(1);
        for (int i = 2; i <= n; i++){
            if (a[i] == '0')    continue;
            else vec.pb(i - 1), vec.pb(i);
        }
        //将0变成b串,[1,x]使得0串[1,x]都是1,再操作[1,x−1],使得0串的[1,x−1]还原为0
        for (int i = n; i >= 2; i--){
            if (b[i] == '0')    continue;
            else{
                vec.pb(i);
                vec.pb(i - 1);
            }
        }
        if (b[1] == '1')    vec.pb(1);
        //去重, 若是相等且数量为基数则保留一个;偶数则一个不保留
        int last = vec[0], temp = 1;
        for (int i = 1; i < vec.size(); i++){
            if (vec[i] != last){
                if (temp % 2 == 1)    s.pb(last);
                temp = 1, last = vec[i];
            }
            else    temp++;
        }
        if (temp % 2 == 1)    s.pb(last);

        cout << s.size() << " ";
        for (int i = 0; i < s.size(); i++)    cout << s[i] << " ";
        cout << endl;
    }
}

 

posted @ 2020-07-28 21:40  吉吉的奥利奥  阅读(49)  评论(0编辑  收藏