vp 2025夏季PAT甲级

前言

昨天vp了2025秋季的,那场的最后一题给我当头一棒,第4题的最后一组后台测试点无论如何调试都过不去,于是今天来vp这场夏季的,最终80分钟AK。
录屏在:https://www.bilibili.com/video/BV1bMfLBuE1t

题目总览

image
image
image

题目细览

第1题 A-1 Walnut Numbers

image

思路

先将读入的数按二进制位存到数组中,然后判断是否存在连续的三个0或者连续的三个1即可。

我的AC代码

#include <bits/stdc++.h>

void solve() {
  int x;
  std::cin >> x;

  auto check = [&]() {
    int t = x;
    std::vector<int> bit;
    while (t) {
      bit.push_back(t & 1);
      t >>= 1;
    }
    int t0 = 0, t1 = 0;
    for (int i = 0; i < bit.size(); i++) {
      if (bit[i]) {
        if (t0) {
          if (t0 == 3) {
            return true;
          }
          t0 = 0;
        }
        t1++;
      } else {
        if (t1) {
          if (t1 == 3) {
            return true;
          }
          t1 = 0;
        }
        t0++;
      }
    }
    if (t0) {
      if (t0 == 3) {
        return true;
      }
    }
    if (t1) {
      if (t1 == 3) {
        return true;
      }
    }
    return false;
  };

  std::cout << (check() ? "yes\n" : "no\n");
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.tie(nullptr);

  int T = 1;
  std::cin >> T;

  for (int Ti = 0; Ti < T; Ti++) {
    solve();
  }

  return 0;
}

第2题 A-2 Self-reflection of My Phone

image

思路

想到用一个std::set<std::array<int, 2>> set来维护熬夜的天数,再用一个std::map<std::string, int> cnt来维护每个应用id熬夜的天数,最后统计一遍即可。
读数据的时候可能比较恶心,用scanf可能会更方便一点,但是我用习惯了std::cin就直接这样读了,然后用std::stoi将读入的day, hour, minute, second全都转成int。

我的AC代码

#include <bits/stdc++.h>

void solve() {
  int n;
  std::cin >> n;

  std::vector<std::array<std::string, 5>> s(n);
  for (int i = 0; i < n; i++) {
    std::string t1, t2;
    std::cin >> t1 >> t2;
    s[i][0] = t1;
    s[i][1] = t2.substr(0, 3);
    s[i][2] = t2.substr(4, 2);
    s[i][3] = t2.substr(7, 2);
    s[i][4] = t2.substr(10);
  }

  std::set<std::array<int, 2>> set;
  std::map<std::string, int> cnt;
  for (int i = 0; i < n; i++) {
    auto [id, sday, shour, smin, ssec] = s[i];
    int day = std::stoi(sday);
    int hour = std::stoi(shour);
    int min = std::stoi(smin);
    int sec = std::stoi(ssec);

    if (hour >= 3 && hour <= 22) {
      continue;
    }
    if (hour == 23 && min == 0 && sec == 0) {
      continue;
    }

    if (hour == 23) {
      set.insert({day, day + 1});
      cnt[id]++;
    } else {
      set.insert({day - 1, day});
      cnt[id]++;
    }
  }

  std::cout << set.size() << "\n";
  if (set.size() == 0) {
    std::cout << "#\n";
    return;
  }

  int max = 0;
  std::vector<std::string> ans;
  for (const auto& [id, c] : cnt) {
    max = std::max(max, c);
  }
  for (const auto& [id, c] : cnt) {
    if (c == max) {
      ans.push_back(id);
    }
  }
  std::sort(ans.begin(), ans.end());
  for (int i = 0; i < ans.size(); i++) {
    std::cout << ans[i] << " \n"[i + 1 == ans.size()];
  }
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.tie(nullptr);

  int T = 1;
  // std::cin >> T;

  for (int Ti = 0; Ti < T; Ti++) {
    solve();
  }

  return 0;
}

第3题 A-3 Linear Component

image

思路

就是判断无向图中链的数量,特别地,只有一个节点也是一条链。那么想到用并查集来维护连通块,然后枚举每个连通块,看它是否满足是一条链的性质:只有两个节点的度为1且联通块内所有节点的度之和应等于连通块数量减一的两倍,或者该连通块的大小为1(即单个节点的情况)。

我的AC代码

#include <bits/stdc++.h>

struct DSU {
  std::vector<int> f, siz;

  DSU(int n) {
    f.resize(n + 1);
    std::iota(f.begin(), f.end(), 0);
    siz.assign(n + 1, 1);
  }

  int find(int x) {
    if (x != f[x]) {
      f[x] = find(f[x]);
    }
    return f[x];
  }

  bool merge(int u, int v) {
    int fu = find(u), fv = find(v);
    if (fu == fv) {
      return false;
    }
    if (fv > fu) {
      std::swap(fu, fv);
    }
    f[fv] = fu;
    siz[fu] += siz[fv];
    return true;
  }
};

void solve() {
  int n, m;
  std::cin >> n >> m;

  std::vector<std::vector<int>> adj(n + 1);
  DSU dsu(n);
  for (int i = 0; i < m; i++) {
    int u, v;
    std::cin >> u >> v;

    adj[u].push_back(v);
    adj[v].push_back(u);
    dsu.merge(u, v);
  }

  std::map<int, std::vector<int>> map;
  for (int i = 1; i <= n; i++) {
    map[dsu.find(i)].push_back(i);
  }

  int ans1 = 0, ans2 = -1;
  for (const auto& [u, v] : map) {
    int cnt1 = 0;
    int sum = 0;
    for (const auto& i : v) {
      if (adj[i].size() == 1) {
        cnt1++;
      }
      sum += adj[i].size();
    }
    if (cnt1 == 2 && sum == (dsu.siz[u] - 1) * 2 || dsu.siz[u] == 1) {
      ans1++;
      if (sum / 2 > ans2) {
        ans2 = sum / 2;
      }
    }
  }

  std::cout << ans1 << " " << ans2 << "\n";
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.tie(nullptr);

  int T = 1;
  // std::cin >> T;

  for (int Ti = 0; Ti < T; Ti++) {
    solve();
  }

  return 0;
}

第4题 A-4 Get the Maximum Result

image

思路

看到了数据范围n <= 8,很自然地想到枚举全排列去计算最大值,对于每次枚举到的排列,我们使用两个栈来计算中缀表达式(这是很典型的栈的应用),由于题目给定的中缀表达式一定合法,可以省掉很多的特判。

我的AC代码

#include <bits/stdc++.h>

using i64 = long long;

void solve() {
  int n;
  std::cin >> n;

  std::string s;
  std::cin >> s;

  std::vector<int> per(n);
  for (int i = 0; i < n; i++) {
    std::cin >> per[i];
  }
  std::sort(per.begin(), per.end());

  int ans = -1E9;

  do {
    std::vector<int> stk1;
    std::vector<char> stk2;
    int idx = 0;
    for (const auto& c : s) {
      if (c == '(') {
        stk2.push_back(c);
      } else if (c == ')') {
        if (stk2.size() && stk2.back() == '(') {
          stk2.pop_back();
          while (stk2.size() && stk2.back() != '(') {
            auto tmp1 = stk1.back();
            stk1.pop_back();
            auto tmp2 = stk1.back();
            stk1.pop_back();
            if (stk2.back() == '+') {
              stk1.push_back(tmp1 + tmp2);
            } else if (stk2.back() == '-') {
              stk1.push_back(tmp2 - tmp1);
            } else if (stk2.back() == '*') {
              stk1.push_back(tmp1 * tmp2);
            }
            stk2.pop_back();
          }
        }
      } else if (c == 'x') {
        stk1.push_back(per[idx++]);
      } else {
        stk2.push_back(c);
      }
    }
    ans = std::max(ans, stk1.back());
  } while (std::next_permutation(per.begin(), per.end()));

  std::cout << ans << "\n";
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  std::cout.tie(nullptr);

  int T = 1;
  // std::cin >> T;

  for (int Ti = 0; Ti < T; Ti++) {
    solve();
  }

  return 0;
}
posted @ 2026-02-21 06:40  Beau_Will  阅读(12)  评论(0)    收藏  举报