ABC292参加記
4完1ペナ63分 2783位
kokatsuさんのAtCoder Beginner Contest 292での成績:2783位
— kokatsu (@kokatsu_) March 4, 2023
パフォーマンス:874相当
レーティング:1266→1232 (-34) :(#AtCoder #ABC292 https://t.co/biUfXSgDKC
ここ最近レートの増減が激しくてしんどい。。。
コーヒーを淹れてDockerのコンテナを起動しようとしたら、謎のエラーが発生してしまった。 A問題はコードテストを使って解いたが、B問題以降は復旧作業に時間を費やしてしまった。
ABCに向けてコーヒーを入れてくる
— kokatsu (@kokatsu_) March 4, 2023
ぐえー、早解セットだったか
— kokatsu (@kokatsu_) March 4, 2023
Docker🐳の調子が悪くてコーディング環境作るのに時間くってしまった
A問題
toUpper関数を用いて大文字にする。
import std;
void main() {
auto S = readln.chomp.to!(dchar[]);
auto res = std.uni.toUpper(S);
res.writeln;
}
B問題
$N$人の選手のペナルティ数を記憶する配列を用意する。
イエローカードが提示された場合はその選手のペナルティ数を$+1$する。
レッドカードが提示された場合はそのペナルティ数を2にする。
質問を受けた時にその選手のペナルティ数が2以上であれば退場処分を受けているのでYes
と答える。
import std;
void main() {
int N, Q;
readf("%d %d\n", N, Q);
auto cnts = new int[](N+1);
foreach (_; 0 .. Q) {
int i, x;
readf("%d %d\n", i, x);
if (i == 1) ++cnts[x];
else if (i == 2) cnts[x] = 2;
else writeln(cnts[x] >= 2 ? "Yes" : "No");
}
}
C問題
エラトステネスの篩の要領で1から$N$までの約数の個数を数え上げる。 $i (1 \leq i < N)$の範囲で$i$の約数の個数 $\times$ $N-i$の約数の個数を足し合わせる。
import std;
void main() {
long N;
readf("%d\n", N);
auto cnts = new long[](N);
foreach (i; 1 .. N) {
foreach (j; iota(i, N, i)) {
++cnts[j];
}
}
long res;
foreach (i; 1 .. N) {
res += cnts[i] * cnts[N-i];
}
res.writeln;
}
D問題
Union-Findを使って解く。 木の根と頂点の個数が結びつくように気をつける必要がある。
import std;
void main() {
int N, M;
readf("%d %d\n", N, M);
auto cnts = new int[](N);
auto uf = new UnionFind!int(N);
foreach (_; 0 .. M) {
int u, v;
readf("%d %d\n", u, v);
--u, --v;
int a = uf.root(u), b = uf.root(v);
uf.unite(u, v);
int r = uf.root(u);
if (r == a) {
++cnts[a];
}
else {
cnts[r] = cnts[a] + cnts[b] + 1;
}
}
bool isOK = true;
foreach (i; 0 .. N) {
if (uf.root(i) == i) {
isOK &= (uf.size(i) == cnts[i]);
}
}
writeln(isOK ? "Yes" : "No");
}
/// Union-Find
struct UnionFind(T)
if (isIntegral!T) {
/// Constructor
this(T n) nothrow @safe {
len = n;
par.length = len;
cnt.length = len;
foreach (i; 0 .. len) {
par[i] = i;
}
cnt[] = 1;
}
/// Returns the root of x.
T root(T x) nothrow @nogc @safe
in (0 <= x && x < len) {
if (par[x] == x) {
return x;
}
else {
return par[x] = root(par[x]);
}
}
/// Returns whether x and y have the same root.
bool isSame(T x, T y) nothrow @nogc @safe
in (0 <= x && x < len && 0 <= y && y < len) {
return root(x) == root(y);
}
/// Unites x tree and y tree.
void unite(T x, T y) nothrow @nogc @safe
in (0 <= x && x < len && 0 <= y && y < len) {
x = root(x), y = root(y);
if (x == y) {
return;
}
if (cnt[x] > cnt[y]) {
swap(x, y);
}
cnt[y] += cnt[x];
par[x] = y;
}
/// Returns the size of the x tree.
T size(T x) nothrow @nogc @safe
in (0 <= x && x < len) {
return cnt[root(x)];
}
private:
T len;
T[] par;
T[] cnt;
}