AtCoder の問題を解くために必要な実力を付けるために作られた「典型問題」を解いていく企画として、「典型90」があります。
今回は、その内、の76問目である「 Cake Cut(★3)」を解説していきたいと思います。
なにか、間違っているところなどありましたら、@EitaSugiまで、ご指導ご鞭撻の程、よろしくお願い致します!
問題名 【076 – Cake Cut(★3)】
問題概要
N個のピースに分かれた円形のホールケーキがあり、各ピースの大きさが与えられます。このケーキから、連続するピースを選んで、その部分がケーキ全体の大きさのちょうど10分の1になるかどうかを判定する問題です。
考察
循環する数列は2倍して考える
円形のケーキは循環しているので、配列を2倍にして直線的に考えることで、問題をシンプルにすることができます。
しゃくとり法
連続する区間の合計値を求める際に、しゃくとり法を利用します。この方法では、2つのポインタ \(L\) と \(R\) を使って、\(L,R\) の範囲の合計値 sum_LRを効率的に求めることができます。
- sum_LR<K の場合、 R を1つ進めて範囲を広げます。
- ssum_LR>K の場合、 L を1つ進めて範囲を狭めます。
この方法により、\(O(2N)\) で探索することが可能になります。
典型解法:しゃくとり法
コード
N = int(input())
A = list(map(int, input().split()))
A2 = A * 2 # 配列を2倍に
total = sum(A)
K = total // 10 # 全体の大きさの10分の1
if total % 10 != 0: # もし10で割り切れないなら、解は存在しない
print("No")
exit()
else:
left, x = 0, 0
for right in range(2*N): # 2*Nまで探索する
x += A2[right] # rightを1つ進めるたびにxに加える
while x > K: # xがKを超えた場合、leftを進める
x -= A2[left]
left += 1
if x == K: # xがKと等しいならYesを出力
print("Yes")
exit()
print("No")
コメント