A - Square Inequality

水题

B - Intersection

水题,就是找公共区间,维护一下 Lmax,Rmin即可

  1. void solve() {
  2. int n, a, b;
  3. int maxa = -1, minb = 0x3f3f3f3f;
  4. cin >> n;
  5. for (int i = 0; i < n; ++i) {
  6. cin >> a;
  7. maxa = max(maxa, a);
  8. }
  9. for (int i = 0; i < n; ++i) {
  10. cin >> b;
  11. minb = min(minb, b);
  12. }
  13. cout << (minb - maxa + 1 > 0 ? minb - maxa + 1 : 0);
  14. }

C - IPFL

交换两个或者把前一半和后一半交换,求 AtCoder Beginner Contest 199 游记(AB水题,C字符串操作,D搜索,E状压) - 图1 次变换后的结果。

模拟会T,把字符串前后两个分开存,然后进行操作

  1. void solve() {
  2. string s, x, y;
  3. int n, q, a, b, op;
  4. cin >> n >> s >> q;
  5. x = s.substr(0, n), y = s.substr(n, n);
  6. while (q--) {
  7. cin >> op >> a >> b;
  8. if (op == 2) swap(x, y);
  9. else {
  10. a--, b--;
  11. if (a > b) swap(a, b);
  12. if (b < n) swap(x[a], x[b]);
  13. else if (a >= n)
  14. swap(y[a - n], y[b - n]);
  15. else
  16. swap(x[a], y[b - n]);
  17. }
  18. }
  19. cout << x << y;
  20. }

D - RGB Coloring 2

AtCoder Beginner Contest 199 游记(AB水题,C字符串操作,D搜索,E状压) - 图2 个点 AtCoder Beginner Contest 199 游记(AB水题,C字符串操作,D搜索,E状压) - 图3 条边的无向图,求用三种颜色染色后每条边相连的点不同的图有几种。

一看数据范围显然是一个搜索题,不过直接搜索会有一些问题,因为先搜到哪个的不同可能图染色后是相同的,会造成重复,既然如此,那我们随便指定一个顺序就可以了。

  1. using ll = long long;
  2. const int N = 30;
  3. vector<int> e[N], a;
  4. int col[N], v[N][4];
  5. ll ans = 1, cur;
  6. bool vis[N];
  7. void dfs0(int x) {
  8. a.push_back(x);
  9. vis[x] = true;
  10. for (int &y : e[x])
  11. if (!vis[y]) dfs0(y);
  12. }
  13. void dfs(int x) {
  14. if (x == a.size()) {
  15. cur++;
  16. return;
  17. }
  18. for (int i = 1; i <= 3; ++i) {
  19. if (!v[a[x]][i]) {
  20. for (int &y : e[a[x]])
  21. if (!v[y][i]) v[y][i] = a[x];
  22. dfs(x + 1);
  23. for (int &y : e[a[x]])
  24. if (v[y][i] == a[x]) v[y][i] = 0;
  25. }
  26. }
  27. }
  28. void solve() {
  29. int n, m;
  30. cin >> n >> m;
  31. for (int i = 0, u, v; i < m; ++i) {
  32. cin >> u >> v;
  33. e[u].push_back(v);
  34. e[v].push_back(u);
  35. }
  36. for (int i = 1; i <= n; ++i) {
  37. if (!vis[i]) {
  38. cur = 0;
  39. a.resize(0);
  40. dfs0(i);
  41. for (int &y : e[i])
  42. if (!v[y][1]) v[y][1] = i;
  43. dfs(1);
  44. ans = ans * cur * 3;
  45. }
  46. }
  47. cout << ans << "\n";
  48. }

E - Permutation 状压DP

借用一下 Acfboy 的思路

AtCoder Beginner Contest 199 游记(AB水题,C字符串操作,D搜索,E状压) - 图4

  1. // Murabito-B 21/04/26
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. #define int long long
  5. const int N = 20;
  6. struct node {
  7. int x, y, z;
  8. bool operator<(node b) const { return x < b.x; }
  9. } a[N];
  10. int n, m, L[N], R[N], g[N], f[(1 << 19) + 5];
  11. bool flag[(1 << 19) + 5];
  12. int popcount(int x) { return x == 0 ? 0 : popcount(x & (x - 1)) + 1; }
  13. void solve() {
  14. cin >> n >> m;
  15. for (int i = 1; i <= m; ++i) cin >> a[i].x >> a[i].y >> a[i].z;
  16. sort(a + 1, a + 1 + m);
  17. for (int i = 1; i <= n; ++i) {
  18. for (int j = 1; j <= m; ++j) {
  19. if (a[j].x == i) {
  20. L[i] = j;
  21. break;
  22. }
  23. }
  24. for (int j = m; j > 0; --j) {
  25. if (a[j].x == i) {
  26. R[i] = j;
  27. break;
  28. }
  29. }
  30. }
  31. for (int S = 1; S < (1 << n); ++S) {
  32. flag[S] = true;
  33. int k = popcount(S);
  34. if (L[k] == 0) continue;
  35. for (int i = 1; i <= n; ++i) g[i] = 0;
  36. for (int i = 1, j = 1; i <= k; ++i) {
  37. while ((S & (1 << j)) == 0) j++;
  38. for (int l = j; l <= n; ++l) g[l]++;
  39. j++;
  40. }
  41. for (int i = L[k]; i <= R[k]; ++i)
  42. flag[S] &= (g[a[i].y] <= a[i].z);
  43. }
  44. f[0] = 1;
  45. for (int S = 0; S < (1 << n); ++S)
  46. for (int i = 0; i <= 18; ++i)
  47. if (((S & (1 << i)) == 0) && flag[S | (1 << i)]) f[S | (1 << i)] += f[S];
  48. cout << f[(1 << n) - 1];
  49. }
  50. signed main() {
  51. ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  52. solve();
  53. }