671 字
2 分钟
Atcoder_Beginner_Contest_465(A~D题)

题目链接:https://atcoder.jp/contests/abc465/tasks
A - Supermajority
直接判断是否即可。
#include <bits/stdc++.h>
using namespace std;using ll = long long;using ull = unsigned long long;#define endl '\n'#define mod 998244353typedef pair<ll, ll> pll;typedef pair<int, int> pii;
void solved() { int a, b; cin >> a >> b; if(a * 3 > b * 2) cout << "Yes" << endl; else cout << "No" << endl;}
int main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int _ = 1; //cin >> _; while (_--) { solved(); } return 0;}B - Parking 2
我的方法可能相对复杂了,官方答案写循环来累加会更快一些。这里进行了分类讨论计算。先特判和的情况,这两种都是区间全部付,然后根据和的情况分类讨论,然后确定具体的区间计算公式。
#include <bits/stdc++.h>
using namespace std;using ll = long long;using ull = unsigned long long;#define endl '\n'#define mod 998244353typedef pair<ll, ll> pll;typedef pair<int, int> pii;
void solved() { int x, y, l, r, a, b; cin >> x >> y >> l >> r >> a >> b; if(b <= l || a >= r) cout << (b - a) * y << endl; else if(l < b && b <= r && a <= l) cout << (b - l) * x + (l - a) * y << endl; else if(l < b && b <= r && a > l) cout << (b - a) * x << endl; else if(b > r && a <= l) cout << (b - r + l - a) * y + (r -l) * x << endl; else if(b > r && l < a < r) cout << (b - r) * y + (r - a) * x << endl;}
int main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int _ = 1; //cin >> _; while (_--) { solved(); } return 0;}C - Reverse Permutation
这题我们用一个双端队列维护来反转状态。我们可以这样理解,进行一次翻转实际上只是翻转了前项,没有改变他们的相对位置,也就是说后续的操作不会影响它们的相对的位置,一反转就全部一起翻转了。所以对于一个位置,我们只需要考虑它当前应该放在队列前方还是后方,最后根据逆转状态判断,从头开始输出还是从尾开始输出答案即可。
这里的实现我们用一个(初始为未翻转)来记录翻转状态,然后遍历次,每次都判断对应的字符串是否为,如果位就改变翻转状态。然后根据来判断是放队头还是队尾。最后输出结果时也需要根据决定从头开始输出还是从尾开始输出。
#include <bits/stdc++.h>
using namespace std;using ll = long long;using ull = unsigned long long;#define endl '\n'#define mod 998244353typedef pair<ll, ll> pll;typedef pair<int, int> pii;
void solved() { int n; string s; cin >> n >> s;
deque<int> a; bool re = false; for(int i = 1; i <= n;i++){ if(s[i - 1] == 'x'){ if(re) a.push_front(i); else a.push_back(i); } else{ re = !re; if(re) a.push_back(i); else a.push_front(i); } } for(int i = 0; i < n;i++){ int ans; if(re){ ans = a.back(); a.pop_back(); } else{ ans = a.front(); a.pop_front(); } cout << ans << " "; }}
int main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int _ = 1; //cin >> _; while (_--) { solved(); } return 0;}D - X to Y
这题我们需要将它理解为一个树的最短路问题。我们定义这个数的深度为的操作次数,节点的值为。因此这是一颗以为根节点的树,对于一个节点,父节点为,子节点为满足的所有。我们类比一下就可以知道题目说的两种操作就是向上跳(前往唯一的父节点)或者向下跳(前往任意的子节点)。所以对于题目给定的和,求变成需要多少次操作,其意就是给定了两个树的节点,求它们之间最短路的距离。
这里我们可以不需要去真的建图来做,我们可以只模拟一下这个跳一跳的过程。我们让和都分别向上跳,和每跳一步都让步数计数加一,然后一直跳到它们有相同的深度。接着让和同步向上跳,(和都跳了一步,加二)直到它们最终相等,(到达连通点),最后输出即可。
#include <bits/stdc++.h>
using namespace std;using ll = long long;using ull = unsigned long long;#define endl '\n'#define mod 998244353typedef pair<ll, ll> pll;typedef pair<int, int> pii;
void solved() { ll x, y, k; cin >> x >> y >> k;
auto depth = [&](ll val) { ll d = 0; while(val){ val /= k; d++; } return d; }; ll dx = depth(x), dy = depth(y); ll ans = 0; while(dx > dy){ x /= k; dx--; ans++; } while(dy > dx){ y /= k; dy--; ans++; } while(x != y){ x /= k; y /= k; ans += 2; } cout << ans << endl;}
int main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cin >> _; while (_--) { solved(); } return 0;}Atcoder_Beginner_Contest_465(A~D题)
https://mkrari.cn/posts/abc_465/