10.9 总结

T1

还行,考场AC了。

主要思路就是从第一列开始,对于上一列每一个一样的数的区间进行排序,最后检验一下就行了,注意对应的问题。

cpp 复制代码
#include <algorithm>
#include <fstream>
#include <vector>

using namespace std;

const int kMaxN = 305;

ifstream cin("exchange.in");
ofstream cout("exchange.out");

int t, n, m, b[kMaxN], a[kMaxN][kMaxN], l[kMaxN];

int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  for (cin >> t; t; t--) {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
      l[i] = i;
      for (int j = 1; j <= m; j++) {
        cin >> a[i][j];
      }
    }
    vector<pair<int, int>> v;
    v.push_back({1, n});
    for (int i = 1; i <= m; i++) {
      vector<pair<int, int>> o = v;
      v.clear();
      for (auto p : o) {
        int L = p.first, R = p.second;
        for (int j = L; j <= R; j++) {
          b[l[j]] = a[l[j]][i];
        }
        sort(l + L, l + R + 1, [](int x, int y) {
          return b[x] < b[y];
        });
        int u = L;
        for (int j = L; j <= R; j++) {
          if (b[l[j]] != b[l[u]]) {
            if (j - u >= 2) {
              v.push_back({u, j - 1});
            }
            u = j;
          }
        }
        if (R - u + 1 >= 2) {
          v.push_back({u, R});
        }
      }
    }
    bool f = 1;
    for (int i = 1; i <= m; i++) {
      for (int j = 2; j <= n; j++) {
        f &= a[l[j]][i] >= a[l[j - 1]][i];
      }
    }
    cout << (f ? "YES\n" : "NO\n");
  }
  return 0;
}

T2

根据大眼观察法,我们设 A 为 \(0\),B 为 \(1\),C 为 \(2\),那么设这一层的相邻两个是 \(x_1, x_2\),那么上一层的答案就是 \(-(x_1 + x_2) \bmod 3\),然后根据大眼观察法,可以发现是组合数的形式,那么你就AC本题了。

赛事没有想到沟槽的组合数:(
不是哥们?你不会组合数? 组合数公式 C_{m}\^{n} = \\dfrac{m!}{n!(m-n)!},只不过是我不想这样写而已。

cpp 复制代码
#include <fstream>

using namespace std;
using ll = long long;

const int kMod = 3, kMaxN = 2e5 + 1;

ifstream cin("brick.in");
ofstream cout("brick.out");

int t, n, jie[kMaxN];
string s;

void Init() {
  for (int i = 1; i <= 1e5 + 1; i++) {
    jie[i] = jie[i - 1] * i % kMod;
  }
}

ll fpow(ll a, ll b) {
  ll res = 1;
  while (b) {
    (b & 1) && (res = res * a % kMod);
    b >>= 1;
    a = a * a % kMod;
  }
  return res;
}


ll Gt(ll n, ll m) {
  if (n < m) {
    return 0;
  }
  ll res = 1;
  for (ll i = n - m + 1; i <= n; i++) {
    res *= i;
  }
  for (ll i = 1; i <= m; i++) {
    res /= i;
  }
  return res % 3;
}

ll C(ll n, ll m) {
  return (n < m ? 0 : (n <= 10 ? Gt(n, m) : C(n / 3, m / 3) * Gt(n % 3, m % 3) % 3));
}

ll Get(char c) {
  return c == 'A' ? 0 : (c == 'B' ? 1 : 2);
}

char To(ll x) {
  return (x == 1 ? 'B' : x == 0 ? 'A' : 'C');
}

int main() {
  Init();
  for (cin >> t; t; t--) {
    cin >> n >> s;
    ll ans = 0, f = n & 1 ? 1 : -1;
    for (int i = 0; i < n; i++) {
      ans = (ans + Get(s[i]) * C(n - 1, i) % kMod);
    }
    ans *= f;
    cout << To((ans % kMod + kMod) % kMod) << '\n';
  }
  return 0;
}