959 字
2 分钟
Atcoder_Beginner_Contest_462(A~E题)
2026-06-15
浏览量 211 · 访客 12

题目链接:https://atcoder.jp/contests/abc462/tasks

A - Secret Numbers#

新建一个字符串tt拼接遍历ss找出的数字字符输出即可。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define endl '\n'
#define mod 998244353
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
void solved(){
string s, t = "";
cin >> s;
for (auto it : s){
if(it >= '0' && it <= '9'){
t += it;
}
}
cout << t << endl;
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
// cin >> _;
while(_--){
solved();
}
return 0;
}

B - Gift#

我们用一个二维数组记录对应第ii人他分别收到了来自哪些人的礼物。然后遍历二维数组输出收到礼物的个数和对应的送礼人都有谁即可。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define endl '\n'
#define mod 998244353
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
vector<vector<int>> a;
void solved(){
int n;
cin >> n;
a.resize(n + 1);
for(int i = 1; i <= n;i++){
int x;
cin >> x;
while(x--){
int y;
cin >> y;
a[y].push_back(i);
}
}
int cnt = 1;
for(auto it : a){
if(cnt == 1) {cnt++;continue;}
if(it.empty()) cout << 0 << " ";
else cout << it.size() << " ";
for(auto it2 : it){
cout << it2 << " ";
}
cout << endl;
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
// cin >> _;
while(_--){
solved();
}
return 0;
}

C - Not Covered Points#

这题的关键点是我们要找到一个合适的遍历方法去判断当前的点是否满足条件。题意简单来说就是对于两个11NN的排列序列对(x,y)(x, y)。保证对于一个(xi,yi)(x_i, y_i),原点,xx轴和yy轴围起来的矩阵内(不包含边界)不能有其他点,记录有多少个这样的点。我的思路是xx11开始,判断yy是否小于等于前面的最小yy坐标(minyminy),如果满足就说明满足条件,ansans加一。我们可以这样理解,我们现在已经给定了yy轴为矩阵的左边,yy轴为矩阵的下边,现在对于每一个矩阵,我们再给定x=ix = i这个右边,如果想要满足条件我们就需要y=jy = j这个上边不上升(可以递减或者不变),这样我们每一个矩阵的右上端点(xj,yj)(x_j, y_j)划定的矩阵内就都不包含前面一个矩阵的右上端点(xi,yi)(x_i, y_i)了。
如果出现了比目前最小的minyminy要大的yy,则这个坐标不满条件,不计数。后续如果还有满足小于minyminyyy就继续计数,然后更新minyminy即可。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define endl '\n'
#define mod 998244353
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
int a[300010]; //记录对应x = i时,y的值。
void solved(){
int n;
ll ans = 0;
cin >> n;
for(int i = 1; i <= n;i++){
int x, y;
cin >> x >> y;
a[x] = y;
}
//记录目前出现的最小值。
int miny = n + 1;
for(int i = 1; i <= n;i++){
if(a[i] < miny){ //因为是排列,不用考虑相等的情况
ans++;
miny = a[i];
}
}
cout << ans << endl;
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
// cin >> _;
while(_--){
solved();
}
return 0;
}

D - Accomplice#

我们先对有效区间进行化简,对于一个嫌疑人ii它真正能作案的时间为[Si,TiD][S_i, T_i - D],同理另一个嫌疑人jj。那么对于这两个人真正能作案的时间就是[max(Si,Sj),min(TiD,TjD)][max(S_i, S_j), min(T_i - D, T_j - D)],所以对于这个时间段内的时刻都是可以作案的时间。但如果我们每次都两两判断的话就会超时。(复杂度O(N2)O(N^2),而nn2×1052 \times 10^5)所以我们需要换种思路。
这里我们可以通过对时刻进行遍历判断累计作案的人。我们可以这样想,假设对于每一个时刻能作案的有kk个人,那么我们能该时刻能实现共同作案的就是Ck2C^{2}_{k}种情况。我们只需要遍历一次所有时刻[1,1×106][1, 1 \times 10^6]即可,这种做法的时间复杂度为O(N)O(N),完全可行。而对于对应时刻内的可作案人数,我们可以通过对每一个嫌疑人对应的可作案时间区间做差分来优化即可。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define endl '\n'
#define mod 998244353
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
void solved(){
int N, D;
ll ans = 0;
cin >> N >> D;
vector<int> diff(1000010, 0);
for(int i = 1; i <= N; i++){
int S, T;
cin >> S >> T;
int laststart = T - D;
if(S <= laststart){
diff[S]++;
diff[laststart + 1]--;
}
}
ll person = 0;
for(int x = 1; x <= 1000000; x++){
person += diff[x];
ans += person * (person - 1) / 2;
}
cout << ans << endl;
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
// cin >> _;
while(_--){
solved();
}
return 0;
}

E - Alternating Costs#

这题算是一个贪心的数学思维题。根据题意,左右横着走或者上下竖着走的代价是一样的,所以我们计算代价最小可以不考虑正负,直接取绝对值。然后我们可以通过自己手动模拟发现斜着走一格有两种情况:2×A2 \times A2×B2 \times B。所以我们斜着走的情况的代价最小为2×min(A,B)2 \times min(A, B)。然后对于左右横走两格,我们也有两种情况:A+BA + B或者斜着走两次,也就是4×min(A,B)4 \times min(A, B)。然后我们还要注意到一点,我们所需操作的次数和X+YX + Y的奇偶性是相关的,所以当操作数为偶数时,我们可以直接根据上述的方法直接得到最小的代价。而当操作数为奇数时,我们就要判断最后一步的操作哪种是最优的,一共四种情况(上下左右)。我们取最优的一种即可。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define endl '\n'
#define mod 998244353
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
//计算贡献
ll calc_even(ll x, ll y, ll A, ll B){
ll cheap = min(A, B);
ll diagonal = min(x, y);
ll straight = abs(x - y) / 2;
return diagonal * 2 * cheap
+ straight * min(A + B, 4 * cheap);
}
void solved(){
ll A, B, X, Y;
cin >> A >> B >> X >> Y;
//取绝对值
X = abs(X);
Y = abs(Y);
//操作数为偶数
if((X + Y) % 2 == 0){
cout << calc_even(X, Y, A, B) << endl;
return;
}
//操作数为奇数
ll ans = LLONG_MAX;
ans = min(ans, A + calc_even(abs(X - 1), Y, A, B));
ans = min(ans, A + calc_even(X + 1, Y, A, B));
ans = min(ans, B + calc_even(X, abs(Y - 1), A, B));
ans = min(ans, B + calc_even(X, Y + 1, A, B));
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_462(A~E题)
https://mkrari.cn/posts/abc_462/
作者
Mkrari
发布于
2026-06-15
许可协议
CC BY-NC-SA 4.0