Atcoder Beginner Contest 314
比赛情况
A 题直接按照题意用字符串输出就行了,很快切掉。
B 题按照题意模拟,但是各种 WA,吃了三发没过先去看 C。
C 题依然是模拟,这道题比较好写一次就过了,回去调 B。
B 题再吃了 3 发罚时终于过了。
先是没有特判输出 0 导致 vector
为空 WA/RE。
然后没有注意要从小到大输出,cmp
函数漏了一半对下标的判断。
最后是在找数字的时候,按照我的写法,如果全部符合条件,下标不会更新,此时答案为 0,寄。
总之,吃了 6 发罚时,总算是过了。
再开 D 题,一个离线忽略掉对整段序列的大小写修改,只保留最后一次即可。没想到也这么水,40 分钟切完 ABCD。
然后看 EF,一道期望 dp,一道分数取模,直接崩溃,痛骂出题人,摆了一会儿开 G。
G 题一开始想二分,然后想枚举,最后感觉枚举可行,只不过需要一个能在 \(O(\log n)\) 以内维护前 \(K\) 大所有数之和的东西。
不会,寄。
rating:571+33=604
赛时代码
A
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+5;
string s="1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679";
int n;
/*
*/
int main()
{
cin.tie(nullptr) -> sync_with_stdio(false);
// I.N.
cin >> n;
cout << "3.";
for (int i = 0; i < n; ++i) { cout << s[i]; }
// E.D.
return 0;
}
B
#include <bits/stdc++.h>
using namespace std;
const int MAXN=105, MAXC=37;
int n, c[MAXN], x;
vector <int> num_to_p[MAXC];
/*
*/
bool cmp(int a, int b)
{
return (
(c[a] < c[b])
|| (c[a]==c[b] && a<b)
);
}
int main()
{
cin.tie(nullptr) -> sync_with_stdio(false);
// I.N.
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> c[i];
for (int j = 1; j <= c[i]; ++j) {
int a; cin >> a;
num_to_p[a].push_back(i);
}
}
// 特判
cin >> x;
if (num_to_p[x].empty()) { cout << 0 << endl; return 0; }
// 对中奖位置排序
sort(num_to_p[x].begin(), num_to_p[x].end(), cmp);
// 找到符合条件的人
int sz = -1;
for (int i = 1; i < num_to_p[x].size(); ++i) {
if (c[num_to_p[x][i-1]] < c[num_to_p[x][i]]) {
sz=i-1; break;
}
}
sz = (sz==-1? num_to_p[x].size()-1: sz);
// 输出
cout << sz+1 << endl;
for (int i = 0; i <= sz; ++i) {
cout << num_to_p[x][i] << " ";
}
// E.D.
return 0;
}
C
#include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+5;
int n, m;
char s[MAXN];
vector <int> color_to_idx[MAXN];
/*
*/
void operate(int c)
{
int sz = color_to_idx[c].size();
char temp = s[color_to_idx[c][sz-1]];
for (int i = sz-1; i; --i) {
s[color_to_idx[c][i]] = s[color_to_idx[c][i-1]];
}
s[color_to_idx[c][0]] = temp;
}
int main()
{
cin.tie(nullptr) -> sync_with_stdio(false);
// I.N.
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> s[i];
}
for (int i = 1; i <= n; ++i) {
int c; cin >> c;
color_to_idx[c].push_back(i);
}
// 模拟位置变化
for (int i = 1; i <= m; ++i) { operate(i); }
// 输出
for (int i = 1; i <= n; ++i) {
cout << s[i];
}
// E.D.
return 0;
}
D
#include <bits/stdc++.h>
using namespace std;
const int MAXN=5e5+5;
int n, q, status;
char s[MAXN];
/*
*/
char upper_to_lower(char x)
{
if ( ('a' <= x) && (x <= 'z') ) { return x; }
return char(x+'a'-'A');
}
char lower_to_upper(char x)
{
if ( ('A' <= x) && (x <= 'Z') ) { return x; }
return char(x-'a'+'A');
}
struct OP {
int t, x;
char c;
} p[MAXN];
void modify(int t)
{
for (int i = 1; i <= n; ++i) {
s[i] = (t==2? upper_to_lower(s[i]): lower_to_upper(s[i]));
}
}
int main()
{
cin.tie(nullptr) -> sync_with_stdio(false);
// I.N.
cin >> n;
for (int i = 1; i <= n; ++i) { cin >> s[i]; }
// 离线,找到最后一次修改大小写,前面全都不用改
cin >> q;
int last_mdf_all = q+1;
for (int i = 1; i <= q; ++i) {
cin >> p[i].t >> p[i].x >> p[i].c;
if (p[i].t != 1) { last_mdf_all = i; }
}
// 做修改
for (int i = 1; i <= q; ++i) {
if (p[i].t == 1) {
s[ p[i].x ] = p[i].c;
} else if (i == last_mdf_all) {
modify(p[i].t);
}
}
// 输出
for (int i = 1; i <= n; ++i) {
cout << s[i];
}
// E.D.
return 0;
}