日常训练2025-1-19
日常训练2025-1-19
C. Light Switches
rating:1500
思路(Trick)
首先明确一点,当所有的芯片安装完成后,才有可能所有的灯会亮
可以求出芯片安装时刻的最大值max_val
然后就是芯片装好一瞬间就会亮,周期是2k,
现在需要考虑的就是每一个芯片安装时刻到所有装完(max_val)这一段时间是否满足在k内即可
代码
#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, k; std::cin >> n >> k; int maxx = 0; std::vector<int> a(n+1); for (int i = 1; i <= n; i++) { std::cin >> a[i]; maxx = std::max(a[i], maxx); } // l:最后一个灯安装时,没亮的灯中最晚亮的灯需要走l步。 // r:最后一个灯安装时,亮的灯中最早灭的灯在r步后才会灭 int l = 0, r = k; for (int i = 1; i <= n; i++){ int x = (maxx - a[i]) % (2 * k); if (x == k){ l = r + 1; break; } if (x < k){ r = std::min(r, k - x - 1); } if (x > k){ l = std::max(l, 2*k - x); } } if (l > r){ std::cout << "-1\n"; }else{ std::cout << maxx + l << '\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; }
C. Mad MAD Sum
rating:1500
思路(Trick)
b数组是前i个数中,中出现次数大于等于2的最大的数。由此我们可以得出经过一次操作以后,得到的新数组一定是单调不减。此时还有可能出现数量为一的数。,所以我们要再进行一次操作,那样这些只出现一次都数都会被左边替代,这样的话得到的数的出现次数都是大于2。往后就是非零部分向右移动。
代码
#include<bits/stdc++.h> using namespace std ; #define int long long int t; int n; int sum; int maxn; map<int,int> mp ; signed main() { cin>>t ; while(t--) { mp.clear(); cin >> n ; vector<int> a(n+5); sum = 0 ; int maxn = 0 ; for(int i = 0 ; i < n ; i ++ ) { cin >> a[i] ; sum += a[i] ; mp[a[i]] ++ ; if(mp[a[i]] >= 2 && a[i] > maxn) { maxn = a[i] ; } a[i] = maxn ; } mp.clear() ; maxn = 0 ; for(int i = 0 ; i < n ; i ++ ) { sum += a[i] ; mp[a[i]] ++ ; if(mp[a[i]] >= 2 && a[i] > maxn) { maxn = a[i] ; } a[i] = maxn ; } for(int i = 0 ; i < n ; i ++ ) { sum += (n - i) * a[i] ; } cout << sum << endl ; } return 0 ; }
F. Final Boss
rating:1500
思路(二分)
要理解清楚题意,放了 i 号技能,是 i 号技能会陷入冷却,但是我们还可以用其他技能,角色是不会陷入冷却的。所以如果知道回合数 x 的情况下,我们可以很快的算出我们能用多少个 i 号技能,对于其他任何技能也一样可以很快算出来。所以标准的二分题。答案满足单调性,猜测答案的情况下很容易判断是否可行。
评述
原本在想这道题会不会是DP,结果DP有点难,贪心也不现实。看了一眼Jiangly的代码,二分秒了。
代码
#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 h, n; std::cin >> h >> n; std::vector<int> v(n+1), w(n+1); for (int i = 1; i <= n; i++){ std::cin >> v[i]; } for (int i = 1; i <= n; i++){ std::cin >> w[i]; } i64 l = 1, r = 1e11; while (l < r){ i64 x = (l + r) >> 1; i64 dmg = 0; for (int i = 1; i <= n; i++){ dmg += (x + w[i] - 1) / w[i] * v[i]; if (dmg >= h) break; } if (dmg >= h){ r = x; }else{ l = x + 1; } } std::cout << l << '\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; }
D. Ingenuity-2
rating:1400
思路(思维)
由于初始两人在同一点,那么我们想要保证两人最终在同一点,首先,相反方向可以让一个人走,就可以相互抵消,对于没有抵消的部分,如果是偶数次,那么就可以两人一起走,反之,则无解。所以直接判断相反方向的奇偶性是否相同即可。
注意一些特判,n=2时,必须两条指令相同,因为每人至少走一步。对于 n=4,并且每个方向走出现一次的情况。我们也需要分别让每个人走一对相反的方向即可。
代码
#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; using namespace std; void solve() { int n; cin >> n; string s; cin >> s; map<char, int> mp; for (auto c : s) mp[c]++; if (n == 2 && s[0] != s[1]) return cout << "NO\n", void(); if (n == 4 && mp['N'] && mp['S'] && mp['E'] && mp['W']) { for (auto c : s) { if (c == 'N' || c == 'S') cout << "R"; else cout << "H"; } cout << endl; return; } if ((mp['N'] & 1) != (mp['S'] & 1) || (mp['E'] & 1) != (mp['W'] & 1)) return cout << "NO\n", void(); map<char, int> mp2; for (auto c : s) { mp2[c]++; cout << (mp2[c] & 1 ? "R" : "H"); } cout << endl; } 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; }
C. Beautiful Triple Pairs
rating:1400
思路
首先可见三元组的个数并不多, 所以我们可以考虑记录下第一个,第二个相等的个数s1,第一个,第三个相等的个数s2, 第二个,第三个相等的个数s3, 然后在记录全部相等的个数s,那么[x, y, z]能够给答案做出的贡献为s1 + s2 + s3 - 3 * s, 由于种情况会统计两次,所以最后除以2
代码
#include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <set> #include <map> #include <unordered_map> using namespace std; typedef long long ll; typedef pair<int, int> pii; typedef tuple<int, int, int> t3; const int N = 2e5 + 10; ll a[N]; void solve() { int n; cin >> n; for (int i = 0; i < n; i ++ ) cin >> a[i]; map<t3, ll> mp;// 存三元组[x, y, z]的个数 map<t3, ll> mp2;//存[x, y, 0], [x, 0, z], [0,, y, z]的个数 for (ll i = 2; i < n; i ++ ) { mp[{a[i - 2], a[i - 1], a[i]}] ++ ; mp2[{a[i - 2], a[i - 1], 0}] ++ ; mp2[{a[i - 2], 0, a[i]}] ++ ; mp2[{0, a[i - 1], a[i]}] ++ ; } ll res = 0; for (int i = 2; i < n; i ++ ) { res += mp2[{a[i - 2], a[i - 1], 0}]; res += mp2[{a[i - 2], 0, a[i]}]; res += mp2[{0, a[i - 1], a[i]}]; res -= 3 * mp[{a[i - 2], a[i - 1], a[i]}]; // mp[{a[i - 2], a[i - 1], a[i]}] -- ; // mp2[{a[i - 2], a[i - 1], 0}] -- ; // mp2[{a[i - 2], 0, a[i]}] -- ; // mp2[{0, a[i - 1], a[i]}] -- ; } cout << res / 2 << endl; } int main() { int t; cin >> t; while (t -- ) solve(); return 0; }
本文作者:califeee
本文链接:https://www.cnblogs.com/califeee/p/18679224
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步