日常训练2025-1-21
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-19
15.日常训练2025-1-21
16.日常训练2025-1-2217.日常刷题2025-1-2318.日常训练2025-1-2419.日常刷题2025-1-2520.日常刷题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-21
E双生双宿之错
rating:1300
思路(数论)
本题考查中位数定理,中位数有这样的性质 :所有数与中位数的绝对差之和最小。中位数是数列中间的那个数,或者是中间的那两个数之一。
所以最后得到的双生数组中的两种数即为数列左半截的中位数,和右半截的中位数。当左右的中位数相同时,让其中一个 +1 或者 -1,特判一下即可
代码
#include <bits/stdc++.h> typedef std::pair<long long, long long> pll; typedef std::pair<int, int> pii; #define INF 0x3f3f3f3f #define MOD 998244353 using i64 = long long; const int N = 1e5+5; void solve(){ int n; std::cin >> n; std::vector<int> a(n); for (int i = 0; i < n; i++){ std::cin >> a[i]; } std::sort(a.begin(), a.end()); int h = n / 2; int ml = a[h / 2], mr = a[h + h / 2]; i64 ans = INF; for (auto x : {ml, ml - 1}){ for (auto y : {mr, mr + 1}){ if (x == y) continue; i64 res = 0; for (int i = 0; i < h; i++){ res += abs(a[i] - x); } for (int i = h; i < n; i++){ res += abs(a[i] - y); } ans = std::min(ans, res); } } std::cout << ans << '\n'; } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2); int t = 1, i; std::cin >> t; for (i = 0; i < t; i++){ solve(); } return 0; }
J硝基甲苯之袭
rating:1500
思路(优化枚举)
本题考点在于如何利用题目给的信息中隐藏的性质优化枚举。
暴力枚举每一个数,
,显然不可行。但是考虑到 如果 ,则 一定为 i 的因子,设此因子为 g 则公式化为 i ^ j == g。g的范围小了很多,我们能否通过枚举 i 和 g 间接得到 j 呢,显然是可以的。j = i ^ g,此时我们已经验证了 i ^ j == g 的,还需要验证 ,只要满足我们就统计答案。
代码
#include <bits/stdc++.h> typedef std::pair<long long, long long> pll; typedef std::pair<int, int> pii; #define INF 0x3f3f3f3f #define MOD 998244353 using i64 = long long; const int N = 1e5+5; void solve(){ int n; std::cin >> n; std::vector<int> a(n); for (int i = 0; i < n; i++) std::cin >> a[i]; int maxx = *std::max_element(a.begin(), a.end()); std::vector<int> cnt(maxx+1); for (int i = 0; i < n; i++){ cnt[a[i]] += 1; } i64 ans = 0; for (int g = 1; g <= maxx; g++){ for (int i = g; i <= maxx; i += g){ int j = i ^ g; if (i < j && std::gcd(i, j) == g && j <= maxx){ ans += 1LL * cnt[i] * cnt[j]; } } } std::cout << ans << '\n'; } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2); int t = 1, i; for (i = 0; i < t; i++){ solve(); } return 0; }
井然有序之窗
rating:1600
思路(贪心)
我们先将所有区间排序,用一个优先队列来维护“可选的区间右端点”。当我们指定某个区间为ii的时候,我们首先将所有以ii为左端点的区间加入优先队列,然后尽量选择目前最小的那个右端点即可。
代码
#include <bits/stdc++.h> using i64 = long long; using u64 = unsigned long long; using u32 = unsigned; using u128 = unsigned __int128; int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n; std::cin >> n; std::vector<int> l(n), r(n); std::vector<int> p(n); std::vector<std::vector<int>> vec(n); // vec[i]:表示左端的为 i 的点的集合 for (int i = 0; i < n; i++) { std::cin >> l[i] >> r[i]; l[i]--; vec[l[i]].push_back(i); } std::priority_queue<std::array<int, 2>, std::vector<std::array<int, 2>>, std::greater<>> pq; for (int x = 0; x < n; x++) { for (auto i : vec[x]) { pq.push({r[i], i}); } if (pq.empty()) { std::cout << -1 << "\n"; return 0; } auto [r, i] = pq.top(); pq.pop(); if (x >= r) { std::cout << -1 << "\n"; return 0; } p[i] = x; } for (int i = 0; i < n; i++) { std::cout << p[i] + 1 << " \n"[i == n - 1]; } return 0; }
M数值膨胀之美
rating:1400
思路(模拟+贪心)
让包含初始最小值的区间逐渐向左右两边扩展,让每一个数都有一次乘2,且统计答案的机会。
代码
#include <bits/stdc++.h> typedef std::pair<long long, long long> pll; typedef std::pair<int, int> pii; #define INF 0x3f3f3f3f #define MOD 998244353 using i64 = long long; const int N = 1e5+5; void solve() { int n; std::cin >> n; std::vector<i64> a(n); std::multiset<i64> s; for (int i = 0; i < n; ++ i) { std::cin >> a[i]; s.insert(a[i]); } i64 ans = 1e18; for (int i = 0; i < n; ++ i) { if (a[i] == *s.begin()) { s.extract(a[i]); s.insert(a[i] * 2); ans = std::min(ans, *s.rbegin() - *s.begin()); int l = i - 1, r = i + 1; while (l >= 0 || r < n) { if ( r >= n || (a[l] == *s.begin() && l >= 0)) { s.extract(a[l]); s.insert(a[l] * 2); ans = std::min(ans, *s.rbegin() - *s.begin()); -- l; } else{ s.extract(a[r]); s.insert(a[r] * 2); ans = std::min(ans, *s.rbegin() - *s.begin()); ++ r; } } break; } } std::cout << ans << "\n"; } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2); int t = 1, i; for (i = 0; i < t; i++){ solve(); } return 0; }
本文作者:califeee
本文链接:https://www.cnblogs.com/califeee/p/18684510
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步