zoukankan      html  css  js  c++  java
  • Codeforces 选做#1

    教练要求做的题,难度可能有些简单。

    Codeforces 22D. Segments

    考虑每个线段按照右节点排序后,贪心选取即可。

    时间复杂度 (mathcal O(nlog n))

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1005;
    
    int n;
    
    struct line {
      int l, r;
    } seg[N];
    
    bool vis[N];
    
    int main() {
      scanf("%d", &n);
      for (int i = 1; i <= n; i++) {
        scanf("%d %d", &seg[i].l, &seg[i].r);
        if (seg[i].l > seg[i].r) swap(seg[i].l, seg[i].r);
      }
      sort(seg + 1, seg + 1 + n, [](line lhs, line rhs) {
        if (lhs.r == rhs.r) return lhs.l < rhs.l;
        return lhs.r < rhs.r;
      });
      vector<int> ans;
      for (int i = 1; i <= n; i++) {
        if (!vis[i]) {
          ans.emplace_back(seg[i].r);
          int j = i + 1;
          while (seg[j].l <= seg[i].r) {
            vis[j] = 1;
            j++;
          }
        }
      }
      printf("%d
    ", ans.size());
      for (auto i : ans) printf("%d ", i);
      return 0;
    }
    

    Codeforces 9D. How many trees?

    (f[i][j]) 表示前 (i) 个数,深度为 (j) 的方案数。

    考虑枚举左右节点的深度,即

    [f[i+1][j]=sum_k f[i][L] imes f[i-k][R] ]

    /*
     * Author: chhokmah
     * Date: 2020-08-22 09:48:35
     */
    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 40;
    
    int n, k;
    long long f[N][N];
    
    int main() {
      scanf("%d %d", &n, &k);
      f[1][1] = f[0][0] = 1;
      for (int i = 1; i < n; i++) {
        for (int j = 0; j <= i; j++) {
          for (int left = 0; left <= i; left++) {
            for (int right = 0; right <= i - j; right++) {
              f[i + 1][max(left, right) + 1] += f[j][left] * f[i - j][right];
            }
          }
        }
      }
      long long ans = 0;
      for (int i = k; i <= n; i++) ans += f[n][i];
      printf("%I64d
    ", ans);
      return 0;
    }
    

    Codeforces 7D. Palindrome Degree

    考虑一个 (mathcal O(nlog n)) 的暴力。

    考虑优化这个暴力,我们记录前缀的答案,然后可以把 (O(log n)) 的缩小优化为 (O(1))

    时间复杂度 (mathcal O(n))

    /*
     * Author: chhokmah
     * Date: 2020-08-22 10:40:34
     */
    #include <bits/stdc++.h>
    
    using namespace std;
    
    constexpr int N = 5e6 + 5;
    
    template <int base, int mod>
    struct hash_st {
      constexpr static int Base = base, P = mod;
    
      int64_t hashp[N], hashs[N], ord[N];
      string s;
      int n;
    
      void prep() {
        ord[0] = 1;
        for (int i = 1; i <= n; i++) ord[i] = ord[i - 1] * Base % P;
        hashp[0] = s[0];
        for (int i = 1; i < n; i++) hashp[i] = (hashp[i - 1] * Base + s[i]) % P;
        hashs[n - 1] = s[n - 1];
        for (int i = n - 2; i >= 0; i--)
          hashs[i] = (hashs[i + 1] * Base + s[i]) % P;
      }
    
      hash_st() {}
      hash_st(string st) { s = st, n = s.length(), prep(); }
    
      void init(string st) { s = st, n = s.length(), prep(); }
    
      int64_t getp(int l, int r) {
        return l == 0 ? hashp[r]
                      : (hashp[r] - hashp[l - 1] * ord[r - l + 1] % P + P) % P;
      }
    
      int64_t gets(int l, int r) {
        return r == n - 1 ? hashs[l]
                          : (hashs[l] - hashs[r + 1] * ord[r - l + 1] % P + P) % P;
      }
    };
    
    string s;
    hash_st<129, 998244353> hash1;
    int dp[N];
    
    bool chk(int l, int r) { return hash1.getp(l, r) == hash1.gets(l, r); }
    
    int main() {
      ios::sync_with_stdio(false);
      cin.tie(0);
      cout.tie(0);
      cin >> s;
      bool flag = 0;
      int n = s.length(), ans = 0;
      for (int i = 1; i < n; i++)
        if (s[0] != s[i]) flag = 1;
      if (!flag) {
        for (int i = 1; i <= n; i++) ans += log2(i) + 1;
        cout << ans << '
    ';
        return 0;
      }
      hash1.init(s);
      for (int i = 0; i < n; i++) {
        int cnt = 0, len = i + 1;
        if (chk(0, i)) {
          dp[i]++;
          len >>= 1;
          if (chk(i - len + 1, i) && len >= 1) dp[i] += dp[len - 1];
          ans += dp[i];
        }
      }
      cout << ans << '
    ';
      return 0;
    }
    

    Codeforces 8E. Beads

    比较好的一道题,我们先考虑概括其约束:

    • 原串 $leq $ 逆串 (iff) 前缀 $leq $ 后缀
    • 原串 $leq $ 反串 (iff)(1) 位为 (0)
    • 原串 $leq $ 逆反串 (iff) 前缀 $leq $ 后缀的逆串

    我们考虑一位一位确定答案,我们需要计算当前这一位为 (0) 的方案数,并不断和 (k) 靠近。

    时间复杂度 (mathcal O(50n^2))

    需要注意奇数的情况的细节处理。

    /*
     * Author: chhokmah
     * Date: 2020-08-22 14:07:51
     */
    #include <bits/stdc++.h>
    
    using namespace std;
    
    int n;
    long long k;
    long long dp[55][2][2];
    int a[55];
    
    long long numberDigitDp(int r, int flag1, int flag2) {
      if (r < n - r + 1) return 1;
      if (dp[r][flag1][flag2] != -1) return dp[r][flag1][flag2];
      long long& ans = dp[r][flag1][flag2];
      ans = 0;
      if (r == n - r + 1) {
        for (int i = 0; i <= 1; i++)
          if (a[r] == i || a[r] == -1)
            if ((!flag2 || (flag2 && i <= (i ^ 1))))
              ans += numberDigitDp(r - 1, flag1 & 1, flag2 & 0);
      } else {
        for (int i = 0; i <= 1; i++)
          if (a[n - r + 1] == i || a[n - r + 1] == -1)
            for (int j = 0; j <= 1; j++)
              if (a[r] == j || a[r] == -1)
                if ((!flag1 || (flag1 && i <= j)) &&
                    (!flag2 || (flag2 && i <= (j ^ 1))))
                  ans += numberDigitDp(r - 1, flag1 & (i == j), flag2 & (i != j));
      }
      return ans;
    }
    
    int main() {
      ios_base::sync_with_stdio(false);
      cin.tie(nullptr);
      cout.tie(nullptr);
      cin >> n >> k;
      memset(a, -1, sizeof a);
      memset(dp, -1, sizeof dp);
      a[1] = 0;
      if (numberDigitDp(n, 1, 1) <= k) {
        printf("-1
    ");
        return 0;
      }
      printf("0");
      for (int i = 2; i <= n; i++) {
        memset(dp, -1, sizeof dp);
        a[i] = 0;
        long long pro = numberDigitDp(n, 1, 1);
        if (pro <= k) {
          printf("1");
          k -= pro;
          a[i] = 1;
        } else
          printf("0");
      }
      return 0;
    }
    
  • 相关阅读:
    Java实现 LeetCode 416 分割等和子集
    Java实现 LeetCode 416 分割等和子集
    在Linux运行期间升级Linux系统(Uboot+kernel+Rootfs)
    【详解】嵌入式开发中固件的烧录方式
    嵌入式系统烧写uboot/bootloader/kernel的一般方法
    Linux下USB烧写uImage kernel
    Xmanager连接CentOS的远程桌面
    命令行利器Tmux
    u-boot中分区和内核MTD分区关系
    uboot环境变量与内核MTD分区关系
  • 原文地址:https://www.cnblogs.com/chhokmah/p/13545979.html
Copyright © 2011-2022 走看看