LoginSignup
0
1

More than 1 year has passed since last update.

AIZU ONLINE JUDGE 「ITP I」40問をpythonで解いてみた

Last updated at Posted at 2021-09-15

本記事では「レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【初級編:競プロを始めよう】」で紹介されているAOJの「Introduction To Programming I」の40問をPythonで解説します。

ITP1_1_A Hello World

ITP1_1_A
print("Hello world")

【解説】 print関数を使用し、Hello Worldを出力します。

詳しい解説はこちら

ITP1_1_B X:Cubic

ITP1_1_B
x = int(input())
print(x**3)

【解説】 input関数はキーボードからの入力を文字列型として受け取るのでint関数で囲み整数型にしてから処理します。

詳しい解説はこちら

ITP1_1_C Rectangle

ITP1_1_C
a, b = map(int, input().split())
print(a*b, 2*(a+b))

【解説】 input().split()を使用し空白区切りで複数の入力を行います。ただし input関数は入力を文字列型として受け取るのでmap関数の第一引数にint関数を設定し、整数型に変換してから変数a,bに設定します。

詳しい解説はこちら

ITP1_1_D Watch

ITP1_1_D
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

ITP1_2_A
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

ITP1_2_B
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

ITP1_2_C
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

ITP1_2_D
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

ITP1_3_A
for _ in range(1000):
    print("Hello World")

【解説】for文を使用し、繰り返し処理を行います。今回は1000回処理を繰り返すのでfor文のイテラブルにrange(1000)を設定します。そうすると0〜999までの1000回処理が行われます。

詳しい解説はこちら

ITP1_3_B Print Test Cases

ITP1_3_B
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

ITP1_3_C
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?

ITP1_3_D
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

ITP1_4_A
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

ITP1_4_B
import math

r = float(input())
print('{0:.6f} {1:.6f}'.format(r*r*math.pi, 2*r*math.pi))
ITP1_4_B(別解)
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

ITP1_4_C
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
ITP1_4_C(別解)
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

ITP1_4_D
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

ITP1_5_A
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

ITP1_5_B
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

ITP1_5_C
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

ITP1_5_D
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

ITP1_6_A
n = int(input())
get_lst = list(map(int, input().split()))
get_lst.reverse()
print(*get_lst)

【解説】reverseメソッドを使用し、リストを逆順に並べ替え表示します。

詳しい解説はこちら

ITP1_6_B Finding Missing Cards

ITP1_6_B
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

ITP1_6_C
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

ITP1_6_D
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

ITP1_7_A
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?

ITP1_7_C
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)
ITP1_7_C(別解)
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

ITP1_7_C
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

ITP1_7_D
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

ITP1_8_A
words = input()
print(words.swapcase())

【解説】input関数を使い、キーボードから文字列を受け取り変数に代入した後、swapcaseメソッドを使用し、大文字と小文字を変換します。

詳しい解説はこちら

ITP1_8_B Sum of Numbers

ITP1_8_B
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

ITP1_8_C
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

ITP1_8_D
s = input()
p = input()
s = s * 2
if s.find(p) != -1:
    print('Yes')
else:
    print('No')

【解説】リング状の文字列からある文字列を作成できるかを考えます。今回の問題ではpsよりも短いという条件がついています。そのためリング2周分で考えれば十分です。リング2周に該当する文字列を作成し、そこでpを作ることができるか調べます。pがあるかを確かめるために文字列のメソッドfindを利用します。findは特定の文字列の位置を取得しますが、文字列がなければ-1を返します。

詳しい解説はこちら

ITP1_9_A Finding a Word

ITP1_9_A
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

ITP1_9_B
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

ITP1_9_C
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

ITP1_9_D
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にするときstartendは文字通りの解釈がされません。こちらの質問が参考になります。今回はreverseしたい範囲を変数に設定し反転、そして、文字の連結を行います。

詳しい解説はこちら

ITP1_10_A Distance

ITP1_10_A
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

ITP1_10_B
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

ITP1_10_C
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 Trueif文を使用し、終了条件の0が入力された際に処理が終了するようにします。続いて、得点をリストとして読み込み、その平均値を求めます。続いて、for文で各得点から平均値を引いたものを2乗し、その合計値を求めます。この合計値(偏差の合計)をデータの総数で割ったもの(分散)を0.5乗して、標準偏差を算出します。

詳しい解説はこちら

ITP1_10_D Distance II

ITP1_10_D
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のチェビシェフの距離は別に計算をして表示します。

詳しい解説はこちら

0
1
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
1