ABC179 復習

A - Plural Form

末尾の文字に従って分岐をします。

s = input()

if s[-1] == 's':
  print(s + 'es')
else:
  print(s + 's')

B - Go to Jail

タプルなどで同時に投げたサイコロの目を保持しておきます。 3回連続の判定は変数なり、現在のindexから2つ先までも同じ目になっているかを見ます。

n = int(input())
d = [tuple(map(int, input().split())) for i in range(n)]

for i in range(n - 2):
  if d[i][0] == d[i][1]:
    if d[i + 1][0] == d[i + 1][1] and d[i + 2][0] == d[i + 2][1]:
      print('Yes')
      break
else:
  print('No')

C - A x B + C

単純に解くとO(N3)になってしまうため、少し工夫が必要になります。 結論から言ってしまうと、BとCは考慮する必要がなく、Aのみ1~Nまで調べれば良いです。よって計算量はO(N)となり、十分間に合います。

n = int(input())

ans = 0

for A in range(1, n):
  #Cが0では条件が成り立たないため、割り切れる場合は1つ前まで
  if n % A == 0:
    ans += n // A - 1
  else:
    ans += n // A

print(ans)

D - Leaping Tak

DPと累積和の合わせ技です。

n, k = map(int, input().split())

l = []
r = []
for i in range(k):
  a, b = map(int, input().split())
  l.append(a)
  r.append(b)

mod = 998244353

dp = [0] * (n + 1)
#1マス目の行き方は1通り
dp[1] = 1
#累積和を保持する配列
dpsum = [0] * (n + 1)
dpsum[1] = 1
#2マス目〜Nマス目まで、遷移できる数を更新する
for i in range(2, n + 1):
  for j in range(k):
    li = i - r[j]
    ri = i - l[j]
    if ri < 0:
      continue
    li = max(1, li)

    dp[i] += (dpsum[ri] - dpsum[li - 1]) % mod
  
  dpsum[i] = dpsum[i - 1] + dp[i]

print(dp[n] % mod)

終わりに

今回の結果でまたレーティングが下がってしまいました。 D問題は解く方向としては間違っていなかったので、また精進あるのみですね。 とりあえずA〜Cはミスなしで行かないとレーティング下がり続けそうです・・。