AtCoder Beginner Contest 278 の A/B/C/D 問題の解法 #ABC278
2024-02-27AtCoder Beginner Contest 278 の A/B/C/D 問題の解法。
実装はこちら atcoder/abc/201-300/278 · michimani/atcoder 。
A - Shift
長さ \(N\) の配列を用意して \(A_1, A_2, \dots, A_N\) を保持する。 \(i = 1,2, \dots, K\) について、 \(A_{i \mod N} = 0\) に更新する。
その後、 \(i = K+1, K+2 , \dots , K+N\) について、 \(A_{i \mod N} \) を順に出力する。
#include <iostream>
#include <vector>
using namespace std;
using ui = unsigned int;
int main()
{
ui n, k;
cin >> n >> k;
vector<ui> a(n, 0);
for (auto &aa : a)
cin >> aa;
for (ui i = 0; i < k; i++)
a[i % n] = 0;
for (ui i = 0; i < n; i++)
{
if (i > 0)
cout << " ";
cout << a[(k + i) % n];
}
cout << endl;
return 0;
}
提出 #50687162 - AtCoder Beginner Contest 278
B - Misjudge the Time
左右に表示される数字に対して 見間違えやすい時刻 かどうかを判定する関数を定義する。その関数でやっていることは下記。
- 左右に表示される値を分割して 左上・左下・右上・右下 に位置するに分ける
- 下記の条件を両方満たす場合に
true
を、そうでない場合にfalse
を返す- 左上と右上を結合してできる値が \(23\) 以下である
- 左下と右下を結合してできる値が \(59\) 以下である
\(H, M\) について、 上記の関数が true
を返すまで \(M\) をインクリメントし、 true
になったときの \(H, M\) を出力して終了する。 \(M\) をインクリメントする際に \(60\) で割った余りを新しい \(M\) の値とし、その値が \(0\) になったときは \(H\) をインクリメントし、 \(24\) で割った余りを新しい \(H\) の値とする。
#include <iostream>
using namespace std;
using ui = unsigned int;
bool is_mj(ui h, ui m)
{
string hs = to_string(h), ms = to_string(m);
ui lu, ld, ru, rd;
if (hs.length() > 1)
{
ld = hs[1] - '0';
lu = hs[0] - '0';
}
else
{
ld = hs[0] - '0';
lu = 0;
}
if (ms.length() > 1)
{
rd = ms[1] - '0';
ru = ms[0] - '0';
}
else
{
rd = ms[0] - '0';
ru = 0;
}
return lu * 10 + ru <= 23 && ld * 10 + rd <= 59;
}
int main()
{
ui h, m;
cin >> h >> m;
while (true)
{
if (is_mj(h, m))
{
cout << h << " " << m << endl;
return 0;
}
m = (m + 1) % 60;
if (m == 0)
h = (h + 1) % 24;
}
return 0;
}
提出 #50686850 - AtCoder Beginner Contest 278
C - FF
\(N \times N\) で boolean を持つ2次元配列を用意して、各 \(T_i\) について下記のように処理を行う。
- \(T_i = 1\) : \((A, B)\) の値を
true
に更新する - \(T_i = 2\) : \((A, B)\) の値を
false
に更新する - \(T_i = 3\) : \((A, B) = true\) かつ \((B, A) = true\) であれば
Yes
を、そうでなければNo
を出力する。
#include <iostream>
#include <map>
using namespace std;
using ui = unsigned int;
int main()
{
ui n, q;
cin >> n >> q;
map<ui, map<ui, bool>> ff;
ui t, a, b;
for (; q--;)
{
cin >> t >> a >> b;
if (t == 1)
ff[a][b] = true;
else if (t == 2)
ff[a][b] = false;
else if (t == 3)
cout << (ff[a][b] && ff[b][a] ? "Yes" : "No") << endl;
}
return 0;
}
提出 #50686510 - AtCoder Beginner Contest 278
D - All Assign Point Add
次の変数を用意する。
- すべての要素を上書きする値。
ull all = -1
- 上書き済みの要素のインデックスを保持する map。
map<ui, bool> changed
各クエリについて下記のように処理を行う。
- \(1 x_q\)
all
を \(x_q\) に更新するchanged
をクリアする
- \(2 i_q x_q\)
all >= 0
かつchanged[i_q] == false
の場合に \(A_{i_q}\) をall
に更新し、changed[i_q]
をtrue
に更新する- \(A_{i_q}\) に \(x_q\) を加算する
- \(3 i_q\)
all >= 0
かつchanged[i_q] == false
の場合に \(A_{i_q}\) をall
に更新し、changed[i_q]
をtrue
に更新する- \(A_{i_q}\) を出力する
#include <iostream>
#include <vector>
#include <map>
using namespace std;
using ui = unsigned int;
using ll = long long;
int main()
{
ui n;
cin >> n;
vector<ll> a(n, 0);
for (auto &aa : a)
cin >> aa;
ui q;
cin >> q;
ui cmd, i;
ll x;
map<ui, bool> changed;
ll all = -1;
for (; q--;)
{
cin >> cmd;
if (cmd == 1)
{
cin >> x;
all = x;
changed = {};
}
else if (cmd == 2)
{
cin >> i >> x;
if (all >= 0 && !changed[i - 1])
{
a[i - 1] = all;
changed[i - 1] = true;
}
a[i - 1] += x;
}
else if (cmd == 3)
{
cin >> i;
if (all >= 0 && !changed[i - 1])
{
a[i - 1] = all;
changed[i - 1] = true;
}
cout << a[i - 1] << endl;
}
else
{
// noop
}
}
return 0;
}
提出 #50687453 - AtCoder Beginner Contest 278
comments powered by Disqus