pontz_rwのブログ

プログラミング等の備忘録

ITP1_10_D: Distance II

ミンコフスキー距離 | プログラミング入門 | Aizu Online Judge

数学に関する問題

解答

問題文で与えられた数式をコードにしていきます。

まず、xとyの距離をそれぞれ計算します。

次に、求めた距離をそれぞれp乗し、その合計を求めます。

そして、求めた合計をpの逆数乗します。

# coding: utf-8

n = input()
xs = map(float, input().split())
ys = map(float, input().split())
abs_d = [abs(x - y) for (x, y) in zip(xs, ys)]
d = [sum([i ** p for i in abs_d]) ** (1 / p) for p in range(1, 4)]
d.append(max(abs_d))

print(*d, sep='\n')

ITP1_10_C: Standard Deviation

標準偏差 | プログラミング入門 | Aizu Online Judge

数学に関する問題

解答1

問題文で与えられた数式をコードにしていきます。

# coding: utf-8

while True:
    n = int(input())
    if n == 0:
        break

    s = list(map(float, input().split()))
    m = sum(s) / n

    a_2 = sum([(x - m) ** 2 for x in s]) / n
    print(a_2 ** 0.5)

解答2

標準ライブラリにあるpstdev()メソッドを使用します。

# coding: utf-8
from statistics import pstdev

while True:
    n = int(input())
    if n == 0:
        break

    s = list(map(float, input().split()))
    print(pstdev(s))

ITP1_10_B: Triangle

三角形 | プログラミング入門 | Aizu Online Judge

数学に関する問題

三角形の面積 S は、

$$ S = \frac{1}{2}ab\sin{C} $$

c の長さは、 c^{2} = a^{2} + b^{2} - 2ab \cos{C} より、

$$ c = \sqrt{a^{2} + b^{2} - 2ab \cos{C}} $$

高さ h は、S = a \times h \div 2 より、

$$ h = \frac{2S}{a} $$

解答

# coding: utf-8
import math

a, b, C = map(float, input().split())
S =  0.5 * a * b * math.sin(C * math.pi / 180)
L = a + b + (a ** 2 + b ** 2 - 2 * a * b * math.cos(C * math.pi / 180)) ** 0.5
h = 2 * S / a

print("%f\n%f\n%f" % (S, L, h))

ITP1_10_A: Distance

距離 | プログラミング入門 | Aizu Online Judge

2点間の距離を求める問題

2点間の距離は、

\sqrt{(x_2 - x_1)^{2} + (y_2 - y_1)^{2}}

で求めることができます。

解答

# coding: utf-8

x1, y1, x2, y2 = map(float, input().split())
print(((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5)

ITP1_9_D: Transformation

文字列変換 | プログラミング入門 | Aizu Online Judge

文字列操作に関する問題

解答

入力値を分割する際の要素数や、文字列操作する際のインデックスに注意します。

# coding: utf-8

str = input()
q = int(input())

for _ in range(q):
    line = input().split()
    c = line[0]
    a = int(line[1])
    b = int(line[2]) + 1

    if c == 'replace':
        str = str[:a] + line[3] + str[b:]
    elif c == 'reverse':
        str = str[:a] + str[a:b][::-1] + str[b:]
    else:
        print(str[a:b])

AtCoder Beginner Contest 001

abc001.contest.atcoder.jp

A - 積雪深差

# coding: utf-8

H1 = int(input())
H2 = int(input())

print(H1 - H2)

B - 視程の通報

問題文に従って条件分岐します。

m = int(input())

if 100 > m:
    print('00')
elif 5000 >= m:
    print("{:02d}".format(m // 100))
elif 30000 >= m:
    print(m // 1000 + 50)
elif 70000 >= m:
    print((m // 1000 - 30) // 5 + 80)
else:
    print(89)

C - 風力観測

round()は偶数寄りに丸めらます。そのため、round(1.5)の結果は2ですが、round(2.5)の結果も2になります。

# coding: utf-8


def deg_to_dir(deg):
    """Summary line.

    風向から方位を返します。

    Args:
        deg (int): 風向

    Returns:
        string: 方位

    """
    degs_list = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
                 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW']
    deg_index = ((deg * 10 + 1125) // 2250) % 16
    return degs_list[deg_index]


def dis_to_w(dis):
    """Summary line.

    風程から風力を返します。

    Args:
        des (int): 風程

    Returns:
        w (int): 風力

    """
    w = -1
    ws_list = [0.0, 0.3, 1.6, 3.4, 5.5, 8.0, 10.8,
               13.9, 17.2, 20.8, 24.5, 28.5, 32.7]
    r_dif = int(dis * 10 + 0.5) / 10
    for n in ws_list:
        if r_dif >= n:
            w += 1
        else:
            break
    return w


def dir_w(deg, dis):
    """Summary line.

    風向、風程から方位と風力を返します。

    Args:
        deg (int): 風向
        des (int): 風程

    Returns:
        (strint, int): (方位, 風力)のタプル

    """
    w = dis_to_w(dis)
    if w == 0:
        dir = 'C'
    else:
        dir = deg_to_dir(deg)
    return (dir, w)

Deg, Dis = map(int, input().split())

result = dir_w(Deg, Dis)

print(*result)

D - 感雨時刻の整理

降り始め・降り終わりをそれぞれ直前・直後の 5 分単位の時刻に丸めます。

降り始めは、5による剰余を引くことで簡単に求めることができます。

# 13:23 の場合、1323 mod 5 = 3 なので、13:23 - 3 = 13:20
start -= start % 5

降り終わりは、5から5による剰余を引いた結果を足すことで、求めることができます。

# 14:01 の場合、1401 mod 5 = 1 なので、14:01 + (5 - 1) = 14:05
end += 5 - end % 5

しかしこの計算では、0分、5分の場合に、余計に5分足してしまうことになります。

# 14:00 の場合、1400 mod 5 = 0 なので、14:00 + (5 - 0) = 14:05
end += 5 - end % 5

そのため、5による剰余が0の場合は0を足し、1から4の場合は5から5による剰余を引いた結果を足すようにします。

そこで、5による剰余に4を足し、5で割った商の整数部分を結果に掛けることにします。そうすることで、剰余が0の場合は0を掛けることになり、結果0を足し、1から4の場合は1を掛けることで結果を足すようになります。

# 14:00 の場合、1400 mod 5 = 0 なので、
# ((4 + 0) // 5) * (5 - 0) = 0 * 5 = 0
# つまり、14:00 + 0 = 14:00
#
# 14:01 の場合、1401 mod 5 = 1 なので、
# ((4 + 1) // 5) * (5 - 1) = 1 * 4 = 4
# つまり、14:00 + 1 = 14:05
end += ((4 + end % 5) // 5) * (5 - end % 5)

最後に、56分以降は、時間(hour)も繰り上げなければなりません。

ここでは、100による剰余を求めることで分(minute)を抜き出し、56分を基準に、つまり、56で割った整数部の商に40を掛けることで時間を繰り上げます。

# 14:56 の場合、 1456 mod 100 = 56 、56 // 56 = 1 なので、
# 1 * 40 = 40
end % 100 // 56 * 40

これで、降り終わりが丸めることができます

# 14:56 の場合、
# 1456 mod 5 = 1 、1456 mod 100 = 56 なので、
# ((4 + 1) // 5) * (5 - 1) + (56 // 56 * 40)
# (1 * 4) + (1 * 40) = 44
# つまり、1456 + 44 = 1500 => 15:00
end += ((4 + end % 5) // 5) * (5 - end % 5) + (end % 100 // 56 * 40)

解答

# coding: utf-8

N = int(input())
times_set = []
results = []
start_index = 0
end_index = 1
tmp_start = -1
tmp_end = -1

for i in range(N):
    start, end = map(int, input().split('-'))
    start -= start % 5
    end += ((4 + end % 5) // 5) * (5 - end % 5) + end % 100 // 56 * 40
    times_set.append([start, end])

times_set.sort()

for time_set in times_set:
    if tmp_start == -1:
        tmp_start = time_set[start_index]
        tmp_end = time_set[end_index]
    elif time_set[start_index] <= tmp_end:
        if tmp_end <= time_set[end_index]:
            tmp_end = time_set[end_index]
    else:
        results.append("{:04d}-{:04d}".format(tmp_start, tmp_end))
        tmp_start = time_set[start_index]
        tmp_end = time_set[end_index]

results.append("{:04d}-{:04d}".format(tmp_start, tmp_end))

for result in results:
    print(result)