GYM 103371 B - Cilantro

香菜面条!

prob.: 给两个01串S和T,S有一个辅助栈,问以T的形式取出之后,第一个取出的字符在原串S中的可能下标的和

ideas:

很奇妙的一个题

因为是01串,当两个串中0和1的数目都相等的时候总能构造一种方案在栈的辅助下使得S变成T

如果S以T的形式取出之后第一个取出的字符在原串中的下标可能值包含mx,则所有在mx之前的相同字符都为可能的解

只要使得T中第一个与尽量后面的字符匹配就行,二分这个位置好像说会T

考虑贪心

尽量使得S中第一个字符匹配后面的T中的靠后的字符,然后匹配第二个字符,匹配到最后只剩下T中第一个能匹配,这时候就是T能匹配的S的最大的下标,指针指一下

参考了下一些佬的代码,佬们写的真好看

code:

#include <bits/stdc++.h>

using namespace std;

const int N = 5000000 + 10;

char s[N], t[N];
int pres[N][2], pret[N][2];

signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

    int n;
    cin >> n;
    cin >> (s + 1) >> (t + 1);

    for (int i = 1; i <= n; ++i) {
        pres[i][0] = pres[i - 1][0];
        pres[i][1] = pres[i - 1][1];
        if (s[i] == 'N') pres[i][0]++;
        else pres[i][1]++;
        pret[i][0] = pret[i - 1][0];
        pret[i][1] = pret[i - 1][1];
        if (t[i] == 'N') pret[i][0]++;
        else pret[i][1]++;
    }

    if (pres[n][1] != pret[n][1]) {
        cout << 0;
        return 0;
    }

    int cur = 1, ps = n, pt = n;
    while (pt > 1) {
        if (s[cur] == t[pt]) {
            ++cur;
            --pt;
            continue;
        }
        int lstps = ps, lstpt = pt;
//        while(ps && pt && pres[lstps][1] - pres[ps][1] != pret[lstpt][1] - pret[pt][1]) {
//            ps--, pt--;
//        }
//        ps--, pt--;
        while (1) {
            ps--, pt--;
            if (ps && pt && pres[lstps][1] - pres[ps][1] == pret[lstpt][1] - pret[pt][1]) break;
        }
    }

    long long ans = 0;
    for (int i = 1; i <= cur; ++i) {
        if (s[i] == t[1]) ans += i;
    }
    cout << ans << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值