2L 水一帖,应该已经结束了。

  1. 并查集
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 9;
    struct UnionFind {
     int id[N];
     int sz[N];
     int cnt;
     int n;
     UnionFind(int n) : n(n) {
         for (int i = 0; i < n; i++) {
             id[i] = i;
             sz[i] = 1;
         }
         cnt = n;
     }
     int find(int x) {
         if (x == id[x]) {
             return id[x];
         }
         return id[x] = find(id[x]);
     }
     void unite(int x, int y) {
         x = find(x);
         y = find(y);
         if (x == y) {
             return;
         }
         if (sz[x] > sz[y]) {
             id[y] = x;
             sz[x] += sz[y];
         } else {
             id[x] = y;
             sz[y] += sz[x];
         }
     }
     int getCnt() {
         int ans = 0;
         for (int i = 0; i < n; i++) {
             if (id[i] == i) {
                 ans++;
             }
         }
         return ans;
     }
    };
    int main() {
      int n;
      scanf("%d", &n);
      UnionFind* unionFind = new UnionFind(n);
      for (int i = 0; i < n; i++) {
          for (;;) {
              int x; 
              scanf("%d", &x);
              if (x == 0) {
                  break;
              }
              unionFind->unite(i, x-1);
          }
     }
     printf("%d\n", (unionFind->getCnt()));
    }
    
  2. 不会,骗了 10%
  3. 字符串最小表示法
    #include <bits/stdc++.h>
    using namespace std;
    string mini(string s) {
     string ss(s);
     ss = ss + ss;
     bool flag = false;
     int i = 0, j = 1, k = 0, l = ss.size() / 2, p = 0;
     while (i < l && j < l) {
         k = 0;
         while (ss[i + k] == ss[j + k] && k < l) k++;
         if (k == l) {
             p = i;
             flag = true;
             break;
         }
         if (ss[i + k] > ss[j + k])
             if (i + k + 1 > j) i = i + k + 1; 
             else i = j + 1;
         else if (j + k + 1 > i) j = j + k + 1;
             else j = i + 1;
     }
     if (!flag)
         if (i < j) p = i; 
         else p = j;
     return ss.substr(p, l);
    }
    const int N = 1e5 + 9;
    string a[N];
    string b[N];
    bool solve() {
     int n;
     scanf("%d\n", &n);
     for (int i = 0; i < n; i++) {
         getline(cin, a[i]);
         int len = a[i].size();
         b[i].clear();
         for (int j = len - 1; j >= 0; j--) {
             char c = a[i][j];
             if (c == ' ') c = '*';
             b[i].push_back(c);
         }
         a[i] = mini(a[i]);
         b[i] = mini(b[i]);
     }
     unordered_set<string> st1;
     for (int i = 0; i < n; i++) {
         if (st1.count(a[i])) {
             return true;
         }
         st1.insert(a[i]);
     }
     unordered_set<string> st2;
     for (int i = 0; i < n; i++) {
         if (st2.count(b[i])) {
             return true;
         }
         st2.insert(b[i]);
     }
     for (int i = 0; i < n; i++) {
         if (st1.count(b[i]) && a[i] != b[i]) {
             return true;
         }
     }
     return false;
    }
    int main() {
     int t;
     scanf("%d\n", &t);
     while (t--) {
         if (solve()) {
             puts("Yeah");
         } else {
             puts("Sad");
         }
     }
    }
    
  4. 不会,用t = 1时候的用最长不降子序列骗了 20 %
  5. 根本不会。