michimani.net

AtCoder Beginner Contest 278 の A/B/C/D 問題の解法 #ABC278

2024-02-27

AtCoder Beginner Contest 278 の A/B/C/D 問題の解法。

実装はこちら atcoder/abc/201-300/278 · michimani/atcoder

A - Shift

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

B - Misjudge the Time

左右に表示される数字に対して 見間違えやすい時刻 かどうかを判定する関数を定義する。その関数でやっていることは下記。

  1. 左右に表示される値を分割して 左上・左下・右上・右下 に位置するに分ける
  2. 下記の条件を両方満たす場合に true を、そうでない場合に false を返す
    1. 左上と右上を結合してできる値が \(23\) 以下である
    2. 左下と右下を結合してできる値が \(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

C - FF

\(N \times N\) で boolean を持つ2次元配列を用意して、各 \(T_i\) について下記のように処理を行う。

#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

D - All Assign Point Add

次の変数を用意する。

  1. すべての要素を上書きする値。 ull all = -1
  2. 上書き済みの要素のインデックスを保持する map。 map<ui, bool> changed

各クエリについて下記のように処理を行う。

#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