【比赛链接】
【题解链接】
**【A】**String Game
【思路要点】
- 显然可以二分答案。
- 然后判定 p p p是否为删减后的 t t t的子序列即可。
- 时间复杂度 O ( N L o g N ) O(NLogN) O(NLogN)。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 200005; template <typename T> void chkmax(T &x, T y) { x = max(x, y); } template <typename T> void chkmin(T &x, T y) { x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int n, m, a[MAXN]; char s[MAXN], t[MAXN]; bool flg[MAXN]; bool check(int mid) { memset(flg, 0, sizeof(flg)); for (int i = 1; i <= mid; i++) flg[a[i]] = true; int pos = 1; for (int i = 1; i <= m; i++) { while (pos <= n && !(!flg[pos] && s[pos] == t[i])) pos++; if (pos > n) return false; pos++; } return true; } int main() { scanf("\n%s\n%s", s + 1, t + 1); n = strlen(s + 1); m = strlen(t + 1); for (int i = 1; i <= n; i++) read(a[i]); int l = 0, r = n - m; while (l < r) { int mid = (l + r + 1) / 2; if (check(mid)) l = mid; else r = mid - 1; } writeln(l); return 0; }
**【B】**Bitwise Formula
【思路要点】
- 容易发现问题对于每一位是独立的。
- 对于每一位,枚举其取值 ( 0 / 1 ) (0/1) (0/1),模拟一遍题目中的过程,取较最优者作为答案。
- 时间复杂度 O ( N ∗ M ) O(N*M) O(N∗M)。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 5005; template <typename T> void chkmax(T &x, T y) { x = max(x, y); } template <typename T> void chkmin(T &x, T y) { x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int n, m, now[MAXN]; int x[MAXN], y[MAXN]; string name, rubbish, Min, Max; string opt[MAXN], val[MAXN]; map <string, int> num; int main() { read(n), read(m); for (int i = 1; i <= n; i++) { cin >> name; num[name] = i; cin >> rubbish; cin >> val[i]; if (val[i][0] == '0' || val[i][0] == '1') continue; else { x[i] = num[val[i]]; cin >> opt[i]; cin >> rubbish; y[i] = num[rubbish]; } } for (int j = 0; j < m; j++) { int sumz = 0, sumo = 0; now[0] = 0; for (int i = 1; i <= n; i++) { if (opt[i] == "OR") now[i] = now[x[i]] | now[y[i]]; else if (opt[i] == "AND") now[i] = now[x[i]] & now[y[i]]; else if (opt[i] == "XOR") now[i] = now[x[i]] ^ now[y[i]]; else now[i] = val[i][j] - '0'; sumz += now[i]; } now[0] = 1; for (int i = 1; i <= n; i++) { if (opt[i] == "OR") now[i] = now[x[i]] | now[y[i]]; else if (opt