michimani.net

AtCoder Beginner Contest 060 の A/B/C 問題の解法 #ABC060

2024-01-25

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

実装はこちら atcoder/abc/001-100/060 · michimani/atcoder

A - Shiritori

A - Shiritori

A の末尾と B の先頭、B の末尾と C の先頭がそれぞれ同じ文字かどうかを判定する。

#include <iostream>

using namespace std;

int main()
{
  string a, b, c;
  cin >> a >> b >> c;

  if (a[a.size() - 1] == b[0] && b[b.size() - 1] == c[0])
  {
    cout << "YES" << endl;
  }
  else
  {
    cout << "NO" << endl;
  }

  return 0;
}

提出 #49652307 - AtCoder Beginner Contest 060

B - Choose Integers

B - Choose Integers

整数 x,y,z について、「xy で割ったあまりが z になる」ことと「xzy で割ったあまりが 0 である」ことは同値である。

今回の問題では xA の倍数と考えるので、 A×iCB で割ったあまりが 0 になる i が存在するかどうかを見つける問題となる。

i=1,2,3, と確認していく際の A×iCB で割ったあまりを ri とすると、答えが YES となるような入力についてはどこかのタイミングで ri=0 となる。答えが NO となるような入力については、 ri の現れ方が周期的になる。つまり、 ri=rj 且つ ri+1=rj+1 となるような i,j(i<j) が存在する。このような i,j が現れた時点で答えは NO となる。

#include <iostream>
#include <map>
#include <vector>

using namespace std;
using ui = unsigned int;

int main()
{
  ui a, b, c;
  cin >> a >> b >> c;

  map<ui, ui> rm;
  vector<ui> rv;

  ui x = 1;
  ui pr = 0;
  bool exists = false;
  while (true)
  {
    ui r = (a * x - c) % b;
    if (r == 0)
    {
      cout << "YES" << endl;
      return 0;
    }

    if (rm.count(r) > 0)
    {
      if (exists && rv[rm[r] - 1] == pr)
      {
        cout << "NO" << endl;
        return 0;
      }
      exists = true;
    }
    else
    {
      exists = false;
    }

    rv.push_back(r);
    rm[r] = rv.size() - 1;
    pr = r;
    x++;
  }

  return 0;
}

提出 #49652242 - AtCoder Beginner Contest 060

C - Sentou

C - Sentou

ti(1iN) は 1 人目の人がスイッチを押してからの経過時間なので、単純に i 人目の人がスイッチを押した時刻と考えられる。

i+1 人目の人がスイッチを押した時刻と i 人目の人がスイッチを押した時刻の差が T 未満の場合、まだシャワーが出ている状態であり、 T 以上の場合はシャワーが止まっている状態となる。

シャワーが出ている状態でスイッチを押すと、既に出ているシャワーの残り時間を無視してその時点から T 秒間シャワーが出ることになるので、シャワーが出ている合計時間としては重複している分だけ短くなる。具体的には、 ti+1ti 分だけ合計時間が加算されることになる。

スイッチが押されていない状態では、ti+1ti>=T となるので、合計時間としては min(T,ti+1ti) を加算していけばよい。

#include <iostream>
#include <cmath>

using namespace std;
using ui = unsigned int;

int main()
{
  ui n, t;
  cin >> n >> t;

  ui ans = t;
  ui prev = 0;
  for (ui i = 0; i < n; i++)
  {
    ui tt;
    cin >> tt;

    ans += min(t, tt - prev);

    prev = tt;
  }

  cout << ans << endl;
  return 0;
}

提出 #49634392 - AtCoder Beginner Contest 060