ABC220参戦記

プログラミング

ABC220の参加記録です。
使用言語はPython3、レートは600前後の私が自分の理解した内容で記載していきます。
A問題からC問題までのACコード付きです。

A – Find Multiple

標準入出と簡単な繰り返し処理、条件分岐の問題。
繰り返し処理なしでも答えは出ますが、私は繰り返し処理で提出しました。

Cの1倍の数から順に作っていき、A以上B以下の数であればその数を出力してプログラム終了。
Cを1000倍してもA以上B以下の数字が表れなかったら-1を出力するコードです。

# AtCoder Beginner Contest 220
# A - Find Multiple

A,B,C=map(int,input().split())

for i in range (1,1001):
    if A<=i*C<=B:
        print(i*C)
        exit()
print(-1)

繰り返し処理で答えを求めるのではない場合は、
B以下であり、かつCの倍数が、A以上であればその数を出力し、そうでない場合は-1を出力する。というプログラムでもOKですね。(こちらが想定解っぽいです。)

A,B,C=map(int,input().split())
print(B//C*C) if A<=B//C*C else print(-1)

B – Base K

二進数の変換が出来るかが問われる問題。

Python3では、組み込み関数の int() を利用すると楽です。

# AtCoder Beginner Contest 220
# B - Base K

K=int(input())
A,B=map(str,input().split())

A=int(A,K)
B=int(B,K)
print(A*B)

組み込み関数ではなく、計算するとしたら、N進数を10進数に戻していく繰り返し処理を記述していけばよいですね。

K=int(input())
A,B=map(str,input().split())
A=list(map(int,A))
B=list(map(int,B))
A_base10=0
B_base10=0

base_A=0
while len(A)>0:
    A_base10 += A.pop() * K**base_A
    base_A += 1

base_B=0
while len(B)>0:
    B_base10 += B.pop() * K**base_B
    base_B += 1

print(A_base10 * B_base10)

C – Long Sequence

累積和と二分探索の問題。
解説を見ると累積和も二分探索も必要ありませんでした。。。

以下、この問題を解いたときの方針を記載します。

  • 配列の合計よりもXが大きい時は、配列を何回連結すればよいかわかりそう。
  • 配列の合計を複数回繰り返した後に残っている余りが、配列のどこに位置するかわかればよさそう。

上記二つのうまく活用できるのは、累積和と二分探索だな。ということで、この二つを利用しました。

# AtCoder Beginner Contest 220
# C - Long Sequence

import bisect

N=int(input())
A=list(map(int,input().split()))
X=int(input())

# 累積和を作成
acc_A=[0]
for i in range (N):
    acc_A.append(acc_A[-1]+A[i])

# Aの合計
total_A=acc_A[-1]

# Aを何回繰り返したらよいかの判定要素
    # d:何回繰り返すか
    # m:d回繰り返した後に、必要な数
d,m=divmod(X,total_A)

# 答え用の変数
    # 上で求めたdと配列の長さNを掛けた値
ans=d*N

# d回繰り返した後に、必要な数が累積和のどのindexに入るか
p=bisect.bisect_left(acc_A,m)

# Xと等しい場合は、必要な項数に1足す
if d*total_A+acc_A[p]==X:
    print(ans+p+1)
else:
    print(ans+p)

今回の問題は、Xを超える項数ということで、Xと一致する場合は、場合分けが必要です。
私はここを見逃して1回WAを出しました。

コメント

タイトルとURLをコピーしました