日常刷题2025-1-25
1.日常刷题2025-3-162.日常训练2025-1-23.日常训练2025-1-34.日常训练2025-1-55.日常训练2025-1-86.日常训练2025-1-117.日常训练2025-1-128.日常训练2025-1-139.日常训练2025-1-1410.日常训练2025-1-1511.日常训练2025-1-1612.日常训练2025-1-1713.日常训练2025-1-1814.日常训练2025-1-1915.日常训练2025-1-2116.日常训练2025-1-2217.日常刷题2025-1-2318.日常训练2025-1-24
19.日常刷题2025-1-25
20.日常刷题21.日常刷题2025-2-622.日常刷题2025-2-923.日常刷题2025-2-1424.日常刷题2025-2-1525.日常刷题2025-2-1726.日常刷题2025-2-2027.日常刷题2025-2-2128.日常刷题2025-2-2229.日常刷题2025-2-2430.日常刷题2025-2-2631.日常刷题2025-2-2732.日常刷题2025-2-2833.日常刷题2025-3-134.日常刷题2025-3-235.日常刷题2025-3-336.日常刷题2025-3-537.日常刷题2025-3-638.日常刷题2025-3-739.日常刷题2025-3-840.日常刷题2025-3-941.日常刷题2025-3-1042.日常刷题2023-3-1143.日常刷题2025-3-1344.非常棒的二分和DP日常刷题2025-1-25
绝妙的平衡
rating:1400
思路(树形DP+小巧思)
首先考虑什么情况下会无解?显然是一个父亲和他的所有儿子都是红色节点的时候,此时该节点只能赋值为0,因此无解。 只要没这种情况,我们就可以默认的将所有白色节点赋值为2,然后一旦遇到某红色节点不得不用0的时候,我们将该红色节点和它的任意一个白色儿子同时变成1即可。
代码
#include <bits/stdc++.h> using u64 = unsigned long long; using i64 = long long; typedef std::pair<int, int> pii; const int INF = 0x3f3f3f3f; const int mod = 998244353; const long long LINF = 1e18; void solve(){ int n; std::string s; std::cin >> n >> s; s = ' ' + s; std::vector<int> fa(n+1), ans(n+1, 1); std::vector g(n+1, std::vector<int>()); std::vector<int> dp(n+1, 1); for (int i = 1; i <= n - 1; i++){ std::cin >> fa[i+1]; g[fa[i+1]].push_back(i+1); } auto dfs = [&](auto self, int cur) ->void{ int red = 0; for (auto to : g[cur]){ self(self, to); if (s[to] == 'R') { red++; }else{ dp[cur] += dp[to]; } } if (red == g[cur].size() && s[cur] == 'R'){ std::cout << "-1\n"; exit(0); } if (s[cur] == 'R'){ if (dp[cur] % 3 == 0){ ; }else if (dp[cur] % 3 == 1){ ans[cur] = 2; for (auto to : g[cur]){ if (s[to] != 'R'){ ans[to] = 2; break; } } }else if (dp[cur] % 3 == 2){ ans[cur] = 2; } } }; dfs(dfs, 1); for (int i = 1; i <= n; i++){ std::cout << ans[i]; } std::cout << '\n'; } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(15); int t = 1, i; for (i = 0; i < t; i++){ solve(); } return 0; }
C. Remove Exactly Two
思路(图论)
评述
思考问题非常不全面,太想当然了。没有深刻理解问题。
代码
#include <bits/stdc++.h> using u64 = unsigned long long; using i64 = long long; typedef std::pair<int, int> pii; const int INF = 0x3f3f3f3f; const int mod = 998244353; const long long LINF = 1e18; void solve(){ int n; std::cin >> n; std::vector<int> deg(n+1, 0); std::vector g(n+1, std::vector<int>()); for (int i = 0; i < n - 1; i++){ int u, v; std::cin >> u >> v; g[u].push_back(v); g[v].push_back(u); deg[u]++, deg[v]++; } std::multiset<int> st; for (int i = 1; i <= n; i++) st.insert(deg[i]); int res = 0; auto dfs = [&](auto self, int cur, int fa)->void{ if (fa != -1){ res = std::max(res, deg[cur] + deg[fa] - 2); } for (auto to : g[cur]){ if (to == fa) continue; self(self, to, cur); } st.erase(st.find(deg[cur])); for (auto to : g[cur]){ st.erase(st.find(deg[to])); } if (!st.empty()){ res = std::max(res, deg[cur] - 1 + *st.rbegin()); } st.insert(deg[cur]); for (auto to : g[cur]){ st.insert(deg[to]); } }; dfs(dfs, 1, -1); std::cout << res << '\n'; } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(15); int t = 1, i; std::cin >> t; for (i = 0; i < t; i++){ solve(); } return 0; }
D. Card Game
rating:1400
思路(暴力模拟)
就是模拟
代码
#include <bits/stdc++.h> using i64 = long long; void solve() { int n; std::cin >> n; char tr; std::cin >> tr; std::map<char, std::vector<std::string>> f; for (int i = 0; i < 2 * n; i++) { std::string s; std::cin >> s; f[s[1]].push_back(s); } std::vector<std::array<std::string, 2>> ans; for (auto c : {'C', 'D', 'H', 'S'}) { std::sort(f[c].begin(), f[c].end()); if (c == tr) { continue; } for (int i = 0; i + 1 < f[c].size(); i += 2) { ans.push_back({f[c][i], f[c][i + 1]}); } if (f[c].size() % 2 == 1) { if (f[tr].empty()) { std::cout << "IMPOSSIBLE\n"; return; } auto t = f[tr].back(); f[tr].pop_back(); ans.push_back({f[c].back(), t}); } } for (int i = 0; i + 1 < f[tr].size(); i += 2) { ans.push_back({f[tr][i], f[tr][i + 1]}); } for (auto [x, y] : ans) { std::cout << x << " " << y << "\n"; } } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int t; std::cin >> t; while (t--) { solve(); } return 0; }
C. LR-remainders
rating:1400
思路(小巧思)
题目的问题在于不知道数的顺序,如果知道的话,我们可以很轻易维护出上一个数除以 m 的余数是多少,然后直接用余数乘以下一个数,这样就不用怕越界的问题。但是我们知道每个数删除的顺序,所以我们能够根据它得到每个数处理的顺序。
代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 2e6 + 5; ll pre[maxn]; int num[maxn]; ll mod; ll powmod(ll x, ll y) { if (y == 0) return 1; ll t = powmod(x, y / 2); if (t % 2 == 0) return t * t % mod; else return t * t % mod * x % mod; } ll a[maxn], res[maxn]; void solve() { int n; cin >> n; cin >> mod; ll ans = 1; for (int i = 1; i <= n; i++) { cin >> a[i]; } string s; cin >> s; int l = 1, r = n; stack<int> sta; for (int i = 0; i < n; i++) { if (s[i] == 'L') { sta.push(l++); } else { sta.push(r--); } } ans = 1; for (int i = n; i >= 1; i--) { ll now = a[sta.top()]; sta.pop(); ans = ans * now % mod; res[i] = ans; } for (int i = 1; i <= n; i++) cout << res[i] << " "; cout << endl; } int main() { ios::sync_with_stdio(0); int T; cin >> T; while (T--) solve(); }
E. Anna and the Valentine's Day Gift
rating:1400
思路(博弈)
首先是Anna最后想让数位尽量少,Sasha想让数位尽量多。Anna只能让后导零减少,交替操作中Sasha也能抢到一部分后导零。我们先假设所有数位都被Sasha抢到了,再减去Anna抢到的部分后导零即可。每次抢后导零时都会抢后导零最多的。
代码
#include <bits/stdc++.h> using u64 = unsigned long long; using i64 = long long; typedef std::pair<int, int> pii; const int INF = 0x3f3f3f3f; const int mod = 998244353; const long long LINF = 1e18; void solve(){ int n, m; std::cin >> n >> m; int len = 0; std::vector<std::string> a(n); for (int i = 0; i < n; i++){ std::cin >> a[i]; len += a[i].size(); } std::vector<int> ans; for (int i = 0; i < n; i++){ int r = a[i].size() - 1; while (r >= 0 && a[i][r] == '0'){ r--; } int cnt = a[i].size() - 1 - r; if (cnt == 0) continue; ans.push_back(cnt); } std::sort(ans.begin(), ans.end()); int ll = ans.size(); for (int i = ll - 1; i >= 0; i -= 2){ len -= ans[i]; } std::cout << (len <= m ? "Anna" : "Sasha") << '\n'; } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(15); int t = 1, i; std::cin >> t; for (i = 0; i < t; i++){ solve(); } return 0; }
P1064 [NOIP2006 提高组] 金明的预算方案
rating:普及+/提高
思路(分组背包)
比较板的分组背包,把每个主件看作一个组,由于附件比较少一个最多只有2个,所以可以暴力列举出所有可能,然后跑一个分组背包。
最后有一个样例没有过,原因是默认以为是先读入主件,附件会在后面过来,所以
默认是主件,但是样例#11卡了这个点,来了个先出附件再出主件的样例。
代码
#include <bits/stdc++.h> using u64 = unsigned long long; using i64 = long long; typedef std::pair<int, int> pii; const int INF = 0x3f3f3f3f; const int mod = 998244353; const long long LINF = 1e18; void solve(){ int n, m, cnt = 0; std::cin >> n >> m; std::vector<int> v(n+1), p(n+1); std::map<int, std::vector<int>> dic; for (int i = 1; i <= m; i++){ int fa; std::cin >> v[i] >> p[i] >> fa; p[i] *= v[i]; if (fa == 0) { dic[i].push_back(i); cnt++; } else { dic[fa].push_back(i); } } std::vector g(cnt + 2, std::vector<pii>()); int idx = 1; for (auto [x, arr] : dic){ g[idx].push_back({v[arr[0]], p[arr[0]]}); int allv = 0, allp = 0; for (int i = 1; i < arr.size(); i++){ g[idx].push_back({v[arr[0]]+v[arr[i]], p[arr[0]]+p[arr[i]]}); allv += v[arr[i]], allp += p[arr[i]]; } if (arr.size() == 3) g[idx].push_back({v[arr[0]]+allv, p[arr[0]]+allp}); idx++; } /* f[i][j]:表示前i组物品在不超过j这个价格的情况下重要度和价值的乘积的最大值。 */ std::vector<int> f(n+1); for (int i = 1; i <= cnt; i++){ for (int j = n; j >= 0; j--){ for (int k = 0; k < g[i].size(); k++){ if (j >= g[i][k].first){ f[j] = std::max(f[j], f[j-g[i][k].first] + g[i][k].second); } } } } // for (int i = 0; i <= cnt; i++){ // std::cout << f[i] << ' '; // } std::cout << f[n] << '\n'; } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(15); int t = 1, i; for (i = 0; i < t; i++){ solve(); } return 0; }
本文作者:califeee
本文链接:https://www.cnblogs.com/califeee/p/18690782
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步