The 2022 ICPC Asia Regionals Online Contest (I) 补题

L 题意:给定两个字符串s,t,要求从s串中找出一个子串s'使得s'与t的公共最大子串的长度小于2,

思路: 其实题目的意思就是从s中选出的子串s'中不能存在同t任意字串相同的子串,我们考虑这样一种情况,当si可以接在s'的末尾的时候s',它有两种情况1.它根本不在t中出现,2.它在t中的顺序s'的末尾字符的前面,即,它不能够接的字符的集合是要严格包含且大于s'末尾的字符。这时就有聪明的小朋友要问了,如果s'的末尾字符是第1种情况,该怎么办呢?我们先不考虑这个问题,先考虑如果si为第一种情况该怎么办,答案是将上一个的所有状态加1,因此,我们相当于忽略了这个字符,在dp过程中也就不存在这种情况了。(严格意义上来说,循环时是会循环到这种状态的,但是由于这种状态永远是比其他状态小的(都加1等于都不加1),也就是被忽略了)

dpi,j 前i个以字符j+'a'结尾的最长合法子串长度

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include

//#define int ll
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(0);
#define pb push_back
#define endl '\n'
#define x first
#define y second
#define Endl endl
#define pre(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,b,a) for(int i=b;i>=a;i--)
#define si(x) scanf("%d", &x);
#define sl(x) scanf("%lld", &x);
#define ss(x) scanf("%s", x);
#define YES {puts("YES");return;}
#define NO {puts("NO"); return;}
#define all(x) x.begin(),x.end()

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair PII;
typedef pair PIII;
typedef pair PCI;
typedef pair PIC;
typedef pair PDD;
typedef pair PLL;
const int N = 500010, M = 2 * N, B = N, MOD = 1000000007;
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LLINF = 0x3f3f3f3f3f3f3f3f;

int dx[4] = { -1,0,1,0 }, dy[4] = { 0,1,0,-1 };
int n, m, k;
int dp[N][30];
set ne[30];
char s[N], t[N];
char ord[30];
bool st[30];

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lowbit(ll x) { return x & -x; }
ll qmi(ll a, ll b, ll MOD) {
    ll res = 1;
    while (b) {
        if (b & 1) res = res * a % MOD;
        a = a * a % MOD;
        b >>= 1;
    }
    return res;
}

inline void init() {}

void slove()
{
    cin >> s + 1 >> t + 1;
    n = strlen(s + 1), m = strlen(t + 1);
    
    int flag = 0;
    
    rep(i, m, 1)
    {
        pre(j, 0, 25)
            if (st[j])ne[t[i]-'a'].insert('a' + j);
        st[t[i] - 'a'] = true;
    }

    pre(i, 1, n)
    {
        if (!st[s[i] - 'a']) {
            pre(j, 0, 25)dp[i][j] = dp[i - 1][j] + 1;
        }
        else {
            int k = s[i] - 'a';
            dp[i][k] = 1;
            for (int j = 0; j < 26; j++)
                dp[i][j] = dp[i - 1][j];

            for (int j = 0; j < 26; j++)
            {
                if (ne[j].count(s[i]))continue;
                dp[i][k] = max(dp[i][k], dp[i - 1][j] + 1);
            }
        }
    }
    int res = 0;
    pre(i, 0, 25) res = max(res, dp[n][i]);

    cout << res << endl;
} 

signed main()
{
    //IOS;
    int _;
    //si(_);
    _ = 1;
    init();
    while (_--)
    {
        slove();
    }
    return 0;
}

你可能感兴趣的:(ICPC,蓝桥杯,c++,职场和发展)