本記事では「レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【初級編:競プロを始めよう】」で紹介されているAOJの「Introduction To Programming I」の40問をPythonで解説します。
ITP1_1_A Hello World
print("Hello world")
【解説】 print
関数を使用し、Hello World
を出力します。
詳しい解説はこちら
ITP1_1_B X:Cubic
x = int(input())
print(x**3)
【解説】 input
関数はキーボードからの入力を文字列型として受け取るのでint
関数で囲み整数型にしてから処理します。
詳しい解説はこちら
ITP1_1_C Rectangle
a, b = map(int, input().split())
print(a*b, 2*(a+b))
【解説】 input().split()
を使用し空白区切りで複数の入力を行います。ただし input
関数は入力を文字列型として受け取るのでmap
関数の第一引数にint
関数を設定し、整数型に変換してから変数a,bに設定します。
詳しい解説はこちら
ITP1_1_D Watch
s = int(input())
h = s // 3600
m = s % 3600 // 60
s = s % 60
print("{0}:{1}:{2}".format(h, m, s))
【解説】秒数を3600
で割った商がh
に、秒数を3600
で割った余りを60
で割った商がm
に、秒数を60
で割った余りがs
になります。h,m,s
の表示にはformat
関数を使用します。中括弧に挟まれた番号順にformat
関数の引数が設定されます。
詳しい解説はこちら
ITP1_2_A Small, Large, or Equal
a, b = map(int, input().split())
if a > b:
print('a > b')
elif a < b:
print('a < b')
elif a == b:
print('a == b')
else:
pass
【解説】 map
関数で2つの整数値を取得し、変数に設定します。そして、if文で大小比較を行い、それに応じた表示を行います。
詳しい解説はこちら
ITP1_2_B Range
a, b, c = map(int, input().split())
if a < b < c:
print('Yes')
else:
print('No')
【解説】 map
関数で3つの整数値を取得し、変数に設定します。そして、if
文で大小比較しその結果を表示します。
※ a < b and b < c
と記述しても問題ありません。
詳しい解説はこちら
ITP1_2_C Sorting Three Numbers
get_lst = list(map(int, input().split()))
get_lst.sort()
print(*get_lst)
【解説】list
は複数の要素を含むオブジェクトです。map
関数を使用し、整数型(int型)として受け取った複数の値をlist
型として変数に設定します。リスト名.sort()
とすることで昇順に並べ替え、print
関数での表示の際には、リスト名の前にアスタリスクをつけてリストの中身を表示します。
詳しい解説はこちら
ITP1_2_D Circle in a Rectangle
W, H, x, y, r = map(int, input().split())
if x - r < 0:
print("No")
elif y - r < 0:
print("No")
elif x + r > W:
print("No")
elif y + r > H:
print("No")
else:
print("Yes")
【解説】横と縦でそれぞれ円が長方形からはみ出さないかを確認します。
下記の場合は長方形から円がはみ出るので、”No”を表示します。
条件式がx – r < 0の場合、x(円のx座標)がr(半径)より小さいため、円が長方形の左側にはみ出ます。
条件式がy – r < 0の場合、y(円のy座標)がr(半径)より小さいため、円が長方形の下側にはみ出ます。
条件式がx + r > Wの場合、x(円のx座標)とr(半径)の合計がW(長方形のx座標)を上回るため、円が長方形の右側にはみ出ます。
条件式がy + r > Hの場合、y(円のy座標)とr(半径)の合計がH(長方形のy座標)を上回るため、円が長方形の上側にはみ出ます。
上記以外の場合、円は長方形の中にあるので、”Yes”を表示します。
詳しい解説はこちら
ITP1_3_A Print Many Hello World
for _ in range(1000):
print("Hello World")
【解説】for文を使用し、繰り返し処理を行います。今回は1000回処理を繰り返すのでfor文のイテラブルにrange(1000)を設定します。そうすると0〜999までの1000回処理が行われます。
詳しい解説はこちら
ITP1_3_B Print Test Cases
num_lst = []
num = 0
while True:
num = int(input())
if num == 0:
break
num_lst.append(num)
for i in range(len(num_lst)):
print('Case {}: {}'.format(i+1, num_lst[i]))
【解説】入力用のループ処理と出力用のループ処理で分けています。入力する数字の総数が不明な(0が入力されるまで処理を続ける必要がある)ため入力用にはwhileループを使用し、0が入力されるまで入力処理、appendメソッドでリストへ追加します。
出力用のループ処理はリストの要素数分行うのでfor文を使用します。len関数の引数にリストを設定し要素数を取得、さらに、range関数で囲み要素数分、出力処理を行います。
詳しい解説はこちら
ITP1_3_C Swapping Two Numbers
while True:
x, y = map(int, input().split())
if x == 0 and y == 0:
break
elif x < y:
print(x, y)
else:
print(y, x)
【解説】while
文とif文を使用し、0 0
が入力されるまで入力処理を実行します。あとはx,y
の大小関係を確認して出力します。
詳しい解説はこちら
ITP1_3_D How Many Divisors?
a, b, c = map(int, input().split())
cnt = 0
for i in range(a, b + 1):
if c % i == 0:
cnt += 1
print(cnt)
【解説】range
関数をfor
文のイテラブルに設定し、a
からb
までfor
文を回します。そして、a
からb
までの中でcの約数がある(余りが0の)場合に、約数を記憶する変数cnt
に+1し、for
文終了後に表示します。
詳しい解説はこちら
ITP1_4_A A/B Problem
a, b = map(int, input().split())
print('{0} {1} {2:.5f}'.format(a//b, a % b, a/b))
【解説】format
関数を使用して計算結果を表示します。//
は商、%
は余り、a/b
を少数第五位まで表示するため、置き換え先を{2:.5f}にします。
詳しい解説はこちら
ITP1_4_B Circle
import math
r = float(input())
print('{0:.6f} {1:.6f}'.format(r*r*math.pi, 2*r*math.pi))
from math import pi
r = float(input())
print('{0:.6f} {1:.6f}'.format(r*r*pi, 2*r*pi))
【解説】input
関数をfloat
関数で囲み、実数として値を受け取ります。mathモジュールをインポートし、円の面積、円周の長さを表示します。
詳しい解説はこちら
ITP1_4_C Simple Calculator
while True:
a, op, b = map(str, input().split())
a = int(a)
b = int(b)
if op == "?":
break
elif op == "+":
print(int(a + b))
elif op == "-":
print(int(a - b))
elif op == "*":
print(int(a * b))
elif op == "/":
print(int(a / b))
else:
pass
while True:
table = input().split()
a = int(table[0])
op = table[1]
b = int(table[2])
if op == "?":
break
elif op == "+":
print(int(a + b))
elif op == "-":
print(int(a - b))
elif op == "*":
print(int(a * b))
elif op == "/":
print(int(a / b))
else:
pass
【解説】2文字目に?
が入力されるまでwhile
ループを実行します。あとは足し算、引き算、掛け算、割り算の演算子に従って計算結果を出力します。
詳しい解説はこちら
ITP1_4_D Min, Max and Sum
n = int(input())
get_lst = list(map(int, input().split()))
print(min(get_lst), max(get_lst), sum(get_lst))
【解説】max
関数、min
関数sum
関数を使用し、最大値、最小値、合計値を表示します。
詳しい解説はこちら
ITP1_5_A Print a Rectangle
while True:
H, W = map(int, input().split())
if H == 0 and W == 0:
break
for i in range(H):
print("#"*W)
print()
【解説】while
文とif
文を使用し、H, Wがともに0が入力されるまで入力を続けます。そして、for
文を使用し、W(横の長さ)分の”#”をH(たての長さ)回繰り返して表示します。
詳しい解説はこちら
ITP1_5_B Print a Frame
while True:
H, W = map(int, input().split())
if H == 0 and W == 0:
break
for i in range(H):
for k in range(W):
if i == 0 or i == H-1 or k == 0 or k == W-1:
print("#", end="")
else:
print(".", end="")
print()
print()
【解説】while
文とif
文を使用し、H, Wがともに0が入力されるまで入力を続けます。
そして、以下のときは描画する四角形の枠と判断し"#"を描画します。
range(H)で0~H-1までの値を取り出す際の0は上の枠
range(H)で0~H-1までの値を取り出す際のH-1は下の枠
range(W)で0~W-1までの値を取り出す際の0は左の枠
range(W)で0~W-1までの値を取り出す際のW-1は右の枠
それ以外は"."を描画します。
詳しい解説はこちら
ITP1_5_C Print a Chessboard
while True:
H, W = map(int, input().split())
if H == 0 and W == 0:
break
for i in range(H):
for j in range(W):
if (i+j) % 2 == 0:
print("#", end="")
else:
print(".", end="")
print()
print()
【解説】while
文とif
文を使用し、H, Wがともに0が入力されるまで入力を続けます。
内側のfor文for j in range(W):
で横の描画、外側のfor文for i in range(H):
でたての描画をする際に、i+jを2で割った余りが0のとき、偶数個目と判断し”#”を描画、それ以外は奇数個目なので”.”を描画します。”#”と”.”を交互に描画するイメージです。横のループがカウントアップする際に、引数に何も設定しない空のprint
文で改行を行います。
詳しい解説はこちら
ITP1_5_D Structured Programming
n = int(input())
for i in range(1, n+1):
if i % 3 == 0 or "3" in str(i):
print(" {}".format(i), end="")
print()
【解説】今回の問題では**「n以下の自然数のうち、3の倍数もしくは3がつく数を小さいものから順に出力しなさい」**という問題です。3の倍数の確認は演算子%
を使用します。3がつく数の確認は注意が必要です。演算子in
を使用し、繰り返し可能なオブジェクトから当てはまる値があるか判定します。今回は、一度str
関数でstr
型に変換した後にその中に”3″があるか確認します。
詳しい解説はこちら
ITP1_6_A Reversing Numbers
n = int(input())
get_lst = list(map(int, input().split()))
get_lst.reverse()
print(*get_lst)
【解説】reverse
メソッドを使用し、リストを逆順に並べ替え表示します。
詳しい解説はこちら
ITP1_6_B Finding Missing Cards
all_cards = [(s, n) for s in ['S', 'H', 'C', 'D'] for n in range(1, 14)]
n = int(input())
hold_cards = []
for _ in range(n):
suit, num = input().split()
num = int(num)
hold_cards.append((suit, num))
for card in all_cards:
if card not in hold_cards:
print(*card)
【解説】ネストしたリスト内包表記[(s, n) for s in ['S', 'H', 'C', 'D'] for n in range(1, 14)]
でトランプの全てのパターンを作成し、一つ目のfor文でn組のカードの取得、二つ目のfor文で不足しているカードの出力を行います。二つ目のfor文では演算子not
を使用し、全ての組み合わせからn組のカード以外のカードの出力を行います。
詳しい解説はこちら
ITP1_6_C Official House
houses = [[[0 for r in range(10)] for f in range(3)] for b in range(4)]
n = int(input())
for i in range(n):
b, f, r, v = map(int, input().split())
houses[b - 1][f - 1][r - 1] += v
for b in range(4):
for f in houses[b]:
print('', *f)
if b != 3:
print('#' * 20)
【解説】まず、[[[0 for r in range(10)] for f in range(3)] for b in range(4)]
で10部屋、3階建ての公舎4棟のグループの作成を行います。続いて、一つ目のfor文で4つの整数b(棟), f(階), r(番目), v(人)の読み込み、houses[b - 1][f - 1][r - 1] += v
で指定の部屋に人数を入れます。最後に二つ目のfor文で出力を行います。出力する変数の前にアスタリスク(*)をつけ、中身のみ表示します。
詳しい解説はこちら
ITP1_6_D Matrix Vector Multiplication
n, m = map(int, input().split())
A = [list(map(int, input().split())) for _ in range(n)]
b = [int(input()) for _ in range(m)]
for i in range(n):
sum = 0
for j in range(m):
sum += A[i][j] * b[j]
print(sum)
【解説】この問題も多次元配列で処理することで解くことができます。
まず、n×mの行列を読み込み変数Aに設定。続いてm×1のベクトルを読み込み変数bに設定。
行列Aのi番目の各要素と列ベクトルbの要素の総和を求めて表示をn回繰り返します。
詳しい解説はこちら
ITP1_7_A Grading
while True:
m, f, r = map(int, input().split())
if m == f == r == -1:
break
if m == -1 or f == -1 or m + f < 30:
print("F")
elif m + f >= 80:
print("A")
elif m + f >= 65:
print("B")
elif m + f >= 50:
print("C")
elif m + f >= 30:
if r >= 50:
print("C")
else:
print("D")
else:
pass
【解説】while
文とif
文を使用し、m, f, rが全て0が入力されるまで入力を続けます。
合計点の条件分岐では、まず成績がFランクの生徒かどうか判断し、続いてelif
で点数の大きい順にAからDまでの条件分岐を行います。プログラムは上から順に実行されるため、点数順にif
文を記述すると条件式の簡略化につながります。
詳しい解説はこちら
ITP1_7_B How many ways?
while True:
n, x = map(int, input().split())
if n == 0 and x == 0:
break
cnt = 0
for i in range(1, n-1):
for j in range(i+1, n):
if j < x - i - j <= n:
cnt += 1
print(cnt)
while True:
n, x = map(int, input().split())
if n == 0 and x == 0:
break
cnt = 0
for i in range(1, n+1):
for j in range(i+1, n+1):
for k in range(j+1, n+1):
if i + j + k == x:
cnt += 1
print(cnt)
【解説】while
文とif
文を使用し、空白区切りで0
が入力されるまで入力を続けます。
はじめに外側のfor文で1からn-1までを選びiの設定します、内側のfor文ではそれより大きいi+1からnを選びjに設定します。あとはx-i-jがjよりも大きくn以下であれば前に選んだ数よりも大きくなり、組み合わせとして成立します。
別解では、for文を3つ使用し、range関数の開始値をずらして設定し、合計値がxと同じ時に組み合わせの一つとしてカウントします。
詳しい解説はこちら
ITP1_7_C Spreadsheet
r, c = map(int, input().split())
sheet = [list(map(int, input().split())) for i in range(r)]
for i in range(r):
sheet[i].append(sum(sheet[i]))
Column_sum = [0]*(c+1)
for j in range(c+1):
for k in range(r):
Column_sum[j] += sheet[k][j]
for i in range(r):
print(*sheet[i])
print(*Column_sum)
【解説】はじめにr*c
の2次元配列の入力を行います。続いて、append
メソッドとsum
関数を使用し、行の合計値を計算、リストの各要素の最後に追加します。続いてのfor文で列の合計値をもとめ、最後の表示用のfor文で行の合計値を追加した行列の表示、続いて、列の合計値の表示を行います。
詳しい解説はこちら
ITP1_7_D Matrix Multiplication
n, m, l = map(int, input().split())
A = [list(map(int, input().split())) for _ in range(n)]
B = [list(map(int, input().split())) for _ in range(m)]
for i in range(n):
C = []
for j in range(l):
tmp = 0
for k in range(m):
tmp += A[i][k] * B[k][j]
C.append(tmp)
print(*C)
【解説】ITP1_6_Dと同様、行列の計算です。行列の計算の性質上、一方の行数と他方の列数(またはその逆)が同じでなければなりません。なので一番内側のfor文で一方の列と他方の行のカウントアップを行い、合計値を算出します。
詳しい解説はこちら
ITP1_8_A Toggling Cases
words = input()
print(words.swapcase())
【解説】input
関数を使い、キーボードから文字列を受け取り変数に代入した後、swapcase
メソッドを使用し、大文字と小文字を変換します。
詳しい解説はこちら
ITP1_8_B Sum of Numbers
while True:
str_x = input()
if str_x == "0":
break
ans = 0
for n in str_x:
ans += int(n)
print(ans)
【解説】ある入力までその処理を続ける場合はwhile True
で無限ループを回し、その中で入力を行い、if文で終了条件を設定、break
文でループ処理を終了します。今回は123
が入力されると、1+2+3
という処理をしたいので、input
関数をint
関数で囲まず、文字列として入力を受け取ります。これは後で使用するfor
文のイテラブル(繰り返し可能なオブジェクト)として文字列を設定すると文字列が一つずつ取り出され、処理を行う事ができるからです。今回はその合計値を出力します。
詳しい解説はこちら
ITP1_8_C Counting Characters
import sys
texts=sys.stdin.read()
texts=texts.lower()
cnt=[0]*26
letters='abcdefghijklmnopqrstuvwxyz'
for x in texts:
i=0
for y in letters:
if x==y:
cnt[i]+=1
i+=1
for i in range(26):
print(letters[i]+" : "+str(cnt[i]))
【解説】今回は複数行かつ行数がわからない英文を読み取らなければならないのでsysモジュールのsys.stdin.read
を利用します。複数行の文字列を複数行のまま受け取ることができます。入力後は、lower
メソッドですべて小文字にして、あらかじめ用意したaからzまでの文字列と比較、一致した場合に配列のカウンタを+1
します。
詳しい解説はこちら
ITP1_8_D Ring
s = input()
p = input()
s = s * 2
if s.find(p) != -1:
print('Yes')
else:
print('No')
【解説】リング状の文字列からある文字列を作成できるかを考えます。今回の問題ではp
はs
よりも短いという条件がついています。そのためリング2周分で考えれば十分です。リング2周に該当する文字列を作成し、そこでp
を作ることができるか調べます。p
があるかを確かめるために文字列のメソッドfind
を利用します。find
は特定の文字列の位置を取得しますが、文字列がなければ-1
を返します。
詳しい解説はこちら
ITP1_9_A Finding a Word
word = input()
cnt = 0
while True:
sentence = input()
if sentence == "END_OF_TEXT":
break
else:
cnt += sentence.lower().split().count(word)
print(cnt)
【解説】まずinput関数で単語の入力を行います。while文で"END_OF_TEXT"が入力されるまで入力処理を行います。文字数をカウントする際に使用するsentence.lower().split().count(word)
について解説します。lower()
メソッドで小文字にします。split()
メソッドでスペースごとに区切りリストにします。リストのなかに含まれる個数を調べるにはcount
メソッドを利用します。
詳しい解説はこちら
ITP1_9_B Shuffle
while True:
cards = input()
if cards == "-":
break
m = int(input())
for _ in range(m):
sh = int(input())
former = cards[:sh]
later = cards[sh:]
cards = later+former
print(cards)
【解説】リストのスライスを利用して解くことができます。指定の文字位置より前と後に分けて変数に設定し、交換したものを表示します。
詳しい解説はこちら
ITP1_9_C Card Game
n = int(input())
T = 0
H = 0
for i in range(n):
card_t, card_h = input().split()
if card_t == card_h:
T += 1
H += 1
else:
if card_h > card_t:
H += 3
else:
T += 3
print(T, H)
【解説】文字列に>
や<
を用いると、辞書順で比較した結果が返されます。これを利用して解くことができます。
詳しい解説はこちら
ITP1_9_D Transformation
text = input()
q = int(input())
for _ in range(q):
order = input().split()
a, b = map(int, order[1:3])
if order[0] == "print":
print(text[a:b+1])
elif order[0] == "reverse":
re_text = text[a:b+1]
text = text[:a]+re_text[::-1]+text[b+1:]
else:
text = text[:a]+order[3]+text[b+1:]
【解説】先ほどと同じく、リストのスライスを利用して解くことができます。ただしreverse
のときに少し注意が必要です。スライスでstep
を-1
にするときstart
とend
は文字通りの解釈がされません。こちらの質問が参考になります。今回はreverse
したい範囲を変数に設定し反転、そして、文字の連結を行います。
詳しい解説はこちら
ITP1_10_A Distance
import math
x1, y1, x2, y2 = map(float, input().split())
print(math.hypot(x2 - x1, y2 - y1))
【解説】mathモジュールの1つであるmath.hypotを使用することで原点から点 (x, y)
のベクトルの長さを求める事ができます。
詳しい解説はこちら
ITP1_10_B Triangle
import math
a, b, C = map(int, input().split())
rad = math.radians(C)
S = 0.5*a*b*math.sin(rad)
h = 2*S/a
c = math.sqrt(a**2+b**2-2*a*b*math.cos(rad))
L = a+b+c
print(S, L, h, sep="\n")
【解説】三角形の面積、周の長さ、高さの求め方はたくさんありますので、math
モジュールを利用して解きます。
詳しい解説はこちら
ITP1_10_C Standard Deviation
while True:
n = int(input())
if n == 0:
break
score = list(map(int, input().split()))
mean = sum(score)/n
var_sum = 0
for i in range(n):
var_sum += (score[i]-mean)**2
print((var_sum/n)**0.5)
【解説】while True
とif
文を使用し、終了条件の0
が入力された際に処理が終了するようにします。続いて、得点をリストとして読み込み、その平均値を求めます。続いて、for
文で各得点から平均値を引いたものを2乗し、その合計値を求めます。この合計値(偏差の合計)をデータの総数で割ったもの(分散)を0.5乗して、標準偏差を算出します。
詳しい解説はこちら
ITP1_10_D Distance II
n = int(input())
X = list(map(int, input().split()))
Y = list(map(int, input().split()))
# p=1,2,3
for p in range(1, 4):
print("{0:.6f}".format(sum([abs(a-b)**p for a, b in zip(X, Y)])**(1/p)))
# p=infinity
print("{0:.6f}".format(max([abs(a-b) for a, b in zip(X, Y)])))
【解説】p=1,2,3のミンコフスキー距離とp=infinityのチェビシェフの距離は別に計算をして表示します。
詳しい解説はこちら