T1:录制节目
可以将原题转化成
有 条线段,可以保留若干条线段,并且可以分成两部分,使得每部分的线段互不相交
先将所有线段按右端点做升序排序,且按左端点做降序排序
然后维护两个变量 last1
和 last2
last1
:第一个部分的最后的端点
last2
:第二个部分的最后的端点
尽量让 更小
原题:P2255
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using P = pair<int, int>; struct line { int l, r; bool operator<(const line& o) const { if (r == o.r) return l > o.l; return r < o.r; }; }; int main() { int n; cin >> n; vector<line> d(n); rep(i, n) cin >> d[i].l >> d[i].r; sort(d.begin(), d.end()); int ans = 0; int last1 = 0, last2 = 0; for (auto [l, r] : d) { if (last1 < last2) swap(last1, last2); if (l >= last1) { ans++; last1 = r; } else if (l >= last2) { ans++; last2 = r; } } cout << ans << '\n'; return 0; }
T2:算式求值(二)
原题:基本计算器
代码实现
#include <bits/stdc++.h> using namespace std; using ll = long long; int main() { string s; cin >> s; int n = s.size(); ll ans = 0; int sign = 1; stack<int> ops; ops.push(1); int i = 0; while (i < n) { if (s[i] == '+') { sign = ops.top(); i++; } else if (s[i] == '-') { sign = -ops.top(); i++; } else if (s[i] == '(') { ops.push(sign); i++; } else if (s[i] == ')') { ops.pop(); i++; } else { ll num = 0; while (i < n and isdigit(s[i])) { num = num*10 + s[i]-'0'; i++; } ans += sign * num; } } cout << ans << '\n'; return 0; }
T3:田忌赛马
先将 和 做升序排序
然后进行分类讨论:
- 如果 剩下的最小值大于 剩下的最小值,则用 剩下的最小值来打 剩下的最小值
- 如果 剩下的最大值大于 剩下的最大值,则用 剩下的最大值来大 剩下的最大值
- 否则用 最小的去消耗 最大的
原题:P1650
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n; cin >> n; vector<int> a(n), b(n); rep(i, n) cin >> a[i]; rep(i, n) cin >> b[i]; sort(a.begin(), a.end()); sort(b.begin(), b.end()); int ans = 0; int l1 = 0, r1 = n-1; int l2 = 0, r2 = n-1; while (l1 <= r1 and l2 <= r2) { if (a[l1] > b[l2]) { ans++; l1++; l2++; } else if (a[r1] > b[r2]) { ans++; r1--; r2--; } else { if (a[l1] < b[r2]) ans--; l1++; r2--; } } cout << ans << '\n'; return 0; }
T4:树的颜色
有三种做法:
- 树上启发式合并
- 树上莫队
- 可以用树上 来统计区间 中每个点对 点 上颜色 的贡献,然后将它容斥掉区间 中的点对颜色 的贡献,就能求出点 的答案。
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n; cin >> n; vector<vector<int>> to(n); for (int i = 1; i < n; ++i) { int p; cin >> p; --p; to[p].push_back(i); } vector<int> c(n); rep(i, n) cin >> c[i], c[i]--; vector<int> cnt(n), ans(n); auto dfs = [&](auto& f, int v) -> void { ans[v] = ++cnt[c[v]]; for (int u : to[v]) { f(f, u); } ans[v] = cnt[c[v]]-ans[v]; }; dfs(dfs, 0); rep(i, n) cout << ans[i] << ' '; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异