codeforces1203D2 思路

個人博客鏈接:https://blog.nuoyanli.com/2020/03/25/cf1203d2/

鏈接

https://codeforces.com/problemset/problem/1203/D2

題意

有一個字符串ss,以及ss中的一個子序列tt,現在要求你將ss刪去最長一段字串,刪去之後tt還是ss的子序列,求刪去的最長字串有多長。

思路

只三種情況,刪去的是ss的前綴、後綴、中間一段。處理也很容易,儘量在ss前面找出tt來,儘量在ss後面找出tt來,並且記錄找出的tt中每一個字符對應在ss中的位置,這個時候刪去前綴後綴就直接解決了問題。中間一段就枚舉從ss前面找xx個字符,後面找t.length()xt.length()−x個字符,因爲之前已經處理了相對的位置,減一下,中間就出來了。

詳細見代碼

參考代碼

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false), cin.tie(0)
#define endl '\n'
#define PB push_back
#define FI first
#define SE second
#define m_p(a, b) make_pair(a, b)
const double pi = acos(-1.0);
const double eps = 1e-9;
typedef long long LL;
const int N = 1e6 + 10;
const int M = 1e5 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const double f = 2.32349;
char s[N], t[N];
int lens, lent, pre[N], suf[N];
// lens爲s的長度,lent爲t的長度,pre記錄t在s儘量前端找出來的時候相對每個字母位置,suf爲後段
int pre_m() { //儘量在s前段找出t來
  int ls = 0, lt = 0, cnt = 0;
  for (int i = 0; i < lens; i++) {
    if (s[ls] == t[lt]) {
      lt++;
      pre[++cnt] = ls;
    }
    ls++;
    if (lt == lent)
      break;
  }

  return lens - ls;
}

int tail_m() { //儘量在s後段找出t來
  int rs = lens - 1, rt = lent - 1, cnt = 0;
  for (int i = lens - 1; i >= 0; i--) {
    if (s[rs] == t[rt]) {
      suf[++cnt] = rs;
      rt--;
    }
    rs--;
    if (rt == -1)
      break;
  }

  return rs + 1;
}
void solve() {
  IOS;
  cin >> s >> t;
  lens = strlen(s);
  lent = strlen(t);
  int ans = 0;
  ans = max(ans, pre_m());
  ans = max(ans, tail_m());
  for (int i = 1; i <= lent; i++) {
    //刪去中間一段,就用前面和後面找出來的位置拼起來
    ans = max(ans, suf[lent - i] - pre[i] - 1);
  }
  cout << ans << endl;
}
signed main() {
  solve();
  return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章