2018 ICPC南京 E - Eva and Euro coins(思维+贪心)

传送门


题目大意

给出一个01序列,现在每次能恰好翻转连续相同的 k k k数,即 0 → 1 , 1 → 0 0 \rightarrow 1, 1 \rightarrow 0 01,10,给出两个序列问能否翻转有限次使得两个序列相互转换。

解题思路

观察样例一,还有如下两个序列:

010010 010010 010010
101101 101101 101101

我们发现是可以相互转换的!首先对于基础的连续 k k k 1 1 1或者 0 0 0,可以直接翻转为 1 1 1,两边如果有不相同的数字,现在已经连成了一片相同的数字,然后可以操作这片相同的片段的任意位置翻转 k k k个。手玩可以发现,我们可以将两边不同的数字向中间传递,最后都消成相同的数字。这启发我们,无需考虑翻转的过程,只要能消完,无需考虑先消哪段,对于原序列已经存在的连续的 k k k 0 , 1 0,1 0,1,可以看做是消消乐那样直接消去,然后两边又拼在一起,最后只需要看两个序列剩余部分是否相等。

//
// Created by Happig on 2020/11/11
//
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>

using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define Vector Point
#define ENDL "\n"
#define lowbit(x) (x&(-x))
#define mkp(x, y) make_pair(x,y)
#define mem(a, x) memset(a,x,sizeof a);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double dinf = 1e300;
const ll INF = 1e18;
const int Mod = 1e9 + 7;
const int maxn = 2e5 + 10;


stack<char> st1;
stack<int> st2;

void solve(string s, string &ans, int k) {
    for (int i = 0; i < s.size(); i++) {
        if (st1.empty()) st1.push(s[i]), st2.push(1);
        else {
            if (st1.top() == s[i]) {
                ++st2.top();
            } else {
                st1.push(s[i]);
                st2.push(1);
            }
            if (st2.top() == k) {
                st1.pop();
                st2.pop();
            }
        }
    }
    while (!st1.empty()) {
        int x = st2.top();
        for (int i = 0; i < x; i++) ans += st1.top();
        st1.pop();
        st2.pop();
    }
}

int main() {
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, k;
    string s, t;
    cin >> n >> k;
    cin >> s >> t;
    if (k == 1) {
        cout << "Yes" << ENDL;
        return 0;
    }
    string s1 = "", s2 = "";
    solve(s, s1, k);
    solve(t, s2, k);
    //cout << s1 << "+" << s2 << endl;
    if (s1 == s2) cout << "Yes" << ENDL;
    else cout << "No" << ENDL;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值