Codeforces Round #712 (Div. 2) B

题目链接
https://codeforces.ml/contest/1504/problem/B
题目截图
Codeforces Round #712 (Div. 2) B
题目大致描述
给定两个01串s与t,其中对s的任意前缀,当0的数量和1的数量相等时,即可进行翻转操作,即将0变成1,1变成0
问:s通过有限次以上操作能否转变成t
题解
这一场。。是一个悲伤的一场。。。我不仅在这场中由蓝降成了青。。而且这场是我打cf以来第一次也是唯一一次我爆零的一场。。。。
首先这场前三题全部是有关字符串的构造题(思维)
A题。。我没怎么多想。。。毕竟是签到题。。。所以就随便写了一个pretest过了就没管了。。。结果最后被fst(tle)了。。。赛后仔细看了一下。。A了
B题。。也就是这题。。。尽管A题我最后被fst了,但并未影响我比赛时的节奏以及情绪。。这题我调了好久。。一直WA。。WA到自闭了
其实我思路大体上是对的,分块贪心,用01相等的前缀来分块,对每一块判断判断st是否满足(即要么异或为0要么同或为0)
这有一个小错误。。。比如:00011 00110这个就不对。。
这个因为没有01相同前缀。。而我对这种情况没处理。。
之后我特判了一下这种情况。。。不过还是WA。。一直WA到自闭(当然途中我切了C的。。不过C也自闭了。。。最终整场下来我爆零了。。。。)
赛后看了一下测试数据然后明白了。。。
10001
01010
这种有一个前缀为可以翻转的。。但是后面却不相同的。。。。正确答案是NO。。而我是YES
只要比较一下后面部分两串是否相等。。。就AC了

再提一下其他的把,尽管这场我很惨。。不过学到了许多。。比如我这个错误数据是第518个。。。cf中是看不到这个数据的,但是我可以单纯将t == 10000且第518数据打印出来,这一就能显示这个数据了(又是一个菜鸡小技巧
然后就是我发现我每个数据都memset一遍时间为到998ms,而事实上没必要,去掉后只有几十ms了,因此以后能不memset就不memset!!!!!

代码如下

#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define IOS std::ios_base::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
typedef long long ll;
typedef unsigned long long ull;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
struct InputOutputStream {
    enum { SIZE = 1000001 };
    char ibuf[SIZE], *s, *t, obuf[SIZE], *oh;
    bool eof;
 
    InputOutputStream() : s(), t(), oh(obuf), eof(false) {}
    ~InputOutputStream() { fwrite(obuf, 1, oh - obuf, stdout); }
 
    explicit operator bool() const {
        return static_cast<bool>(eof == false);
    }
 
    inline char read() {
        if (s == t) t = (s = ibuf) + fread(ibuf, 1, SIZE, stdin);
        return s == t ? -1 : *s++;
    }
 
    inline InputOutputStream &operator>>(char* x) {
        static char c;
        for (c = read(); isspace(c); c = read())
            if (c == -1) {eof = true; return *this;}
        for (; !isspace(c); c = read()) *x = c, ++x;
        *x = 0;
        return *this;
    }
 
    template <typename T>
    inline InputOutputStream &operator>>(T &x) {
        static char c;
        static bool iosig;
        for (c = read(), iosig = false; !isdigit(c); c = read()) {
            if (c == -1) {eof = true; return *this;}
            iosig |= c == '-';
        }
        for (x = 0; isdigit(c); c = read()) x = x * 10 + (c ^ '0');
        if (iosig) x = -x;
        return *this;
    }
 
    inline void print(char c) {
        if (oh == obuf + SIZE) {
            fwrite(obuf, 1, SIZE, stdout);
            oh = obuf;
        }
        *oh++ = c;
    }
 
    template <typename T>
    inline void print(T x) {
        static int buf[23], cnt;
        if (x != 0) {
            if (x < 0) print('-'), x = -x;
            for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 | 48;
            while (cnt) print((char)buf[cnt--]);
        } else print('0');
    }
 
    template <typename T>
    inline InputOutputStream &operator<<(const T &x) {
        print(x);
        return *this;
    }
 
    inline void print(const char* x) {
        for(; *x; x++)
            print(*x);
    }

    inline void print(char* x) {
        for(; *x; x++)
            print(*x);
    }    
} io;

#define cin io
#define cout io

const int maxn = 3e5 + 50;

int t;
int n;
char s1[maxn], s2[maxn];
int cnt1[maxn], cnt2[maxn];//count 1
int tmp[maxn], tot;

bool is_valid(int l, int r) {
    if(s1[l] != s2[l]) { 
        for(int i = l;i <= r;++i) {
            if(s1[i] == s2[i]) { return false; }
        }
    } else {
        for(int i = l;i <= r;++i) {
            if(s1[i] != s2[i]) { return false; }
        }
    }
    return true;
}


signed main() {
    cin >> t;
    for(int _ = 1;_ <= t;++_) {
        // memset(s1, 0, sizeof(s1));
        // memset(s2, 0, sizeof(s2));
        tot = 0;
        cin >> n;
        cin >> (s1 + 1);
        cin >> (s2 + 1);
        // if(_ == 518) {
        //     cout << (s1 + 1) << '\n';
        //     cout << (s2 + 1) << '\n';
        //     return 0;
        // }
        // if(t == 10000) { continue; }
        cnt1[0] = cnt2[0] = 0;
        for(int i = 1;i <= n;++i) {
            cnt1[i] = cnt1[i-1] + (s1[i] == '1');
            cnt2[i] = cnt2[i-1] + (s2[i] == '1');            
        }
        if(cnt1[n] != cnt2[n]) {
            cout << "NO\n";
            continue;
        }
        for(int i = 2;i <= n;i += 2) {
            if(cnt1[i] == i / 2) {
                tmp[++tot] = i;
            }
        }
        int pre = 1;
        bool flag = true;
        for(int i = 1;i <= tot;++i) {
            
            int j = tmp[i];
            // cout << "j: " << j << '\n';
            if(!is_valid(pre, j)) {
                flag = false;
                break;
            }
            pre = j + 1;
        }
        if(strcmp(s1+pre, s2+pre) != 0) {
            flag = false;
        }
        if(flag) {
            cout << "YES\n";
        }  else {
            cout << "NO\n";
        }
    }
    return 0;
}

/*
1
5
10001
01010

*/
上一篇:archlinux安装oh my zsh


下一篇:Windows Terminal && PowerShell