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



题目细览
第1题 A-1 Walnut Numbers

思路
先将读入的数按二进制位存到数组中,然后判断是否存在连续的三个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

思路
想到用一个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

思路
就是判断无向图中链的数量,特别地,只有一个节点也是一条链。那么想到用并查集来维护连通块,然后枚举每个连通块,看它是否满足是一条链的性质:只有两个节点的度为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

思路
看到了数据范围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;
}

浙公网安备 33010602011771号