0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Educational Codeforces Round 82B. National Project

Last updated at Posted at 2020-02-13

題意

  • $n, g, b$ (道の長さ$n$, 晴れの日数$g$, 雨の日数$b$) が与えられる
  • 今日から天気は 晴れ$g$日間, 雨$b$日間, 晴れ$g$日間...を繰り返す
    • つまり、$g=2$, $b=3$なら $ggbbbggbbbggb...$
  • あなたは1日に"1"の道を作っても良い。晴れの日は良い道ができ、雨の日は悪い道ができる。
  • あなたは1日に道を作らなくてもいい
  • あなたはnの半分を良い道で作らないといけない。残りは良い道でも悪い道でもどちらでもよい
  • 半分、とは、$n=4$のとき$2$, $n=5$のとき$3$などである。つまり、$ceil(n/2)$が良い道でないといけない
  • 最短でこの目的を達成するのに何日かかるか?

考察

例を見てもあまりヒントとなる例がないので$n, g, b = 9, 2, 3$を図に示す。

赤が良い道を作る日、緑が悪い道を作る日、黒はおやすみの日である。

まず、rg = 必要な良い道rb = その他必要な道rg = ceil(n/2) = 5としてrb = n-rg = 4は自明である。
良い道だけに着目すると、良い道が埋まるのはceil(rg / g) = xceil(5 / 2) = 3サイクル目になる。つまり、2サイクル目までは必ず必要となり、3サイクル目は図のように、途中で終わる可能性がある。
次に、2サイクル目いっぱいで処理できるどちらでもよい道は$b * 2$サイクルである。($g$の分の作業日はすべて良い道を作るのにあてられる)ただし、この例のように、途中でどちらでもよい道は作り終わってしまうこともある。

以上を考えると3サイクル目に入った瞬間には、rg - g*2 + max(0, rb - b*2)の道を作らないといけない。ここで、良い道は上記の通りこのサイクルで必ず作り終わることが分かっているため、必要な日数は単なる足し算となる。maxを取っているのは$rb - b*2$は負になりうるからである。

実装

q = int(input())
import math
for _ in range(q):
    n, g, b = map(int, input().split())
    rg = math.ceil(n / 2) # 引くべき良い道
    rb = n - rg # 引くべき、どちらでもよい道
    res = 0
    needcycle = math.ceil(rg / g)  # 何回目で引き終わる?
    # 前まででどこまで引き終わった?
    rg = rg - (g * (needcycle - 1)) # 引かないといけない良い道
    rb = max(0, rb - b * (needcycle - 1)) # 引かないといけないどちらでもよい道
    # 必要な日数というのは 前のサイクルまでの日数+最後のサイクルで必要な日数
    res = ((g + b) * (needcycle - 1)) + (rg + rb)
    print(res)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?