ABC001 C - 風力観測

備忘録

問題

atcoder.jp

回答

import sys
import os
import math
import bisect
import itertools
import collections
import heapq
import queue
import array
import time
import numpy as np
from decimal import Decimal, ROUND_HALF_UP

# 時々使う
# from scipy.sparse.csgraph import csgraph_from_dense, floyd_warshall
# from collections import defaultdict, deque

# 再帰の制限設定
sys.setrecursionlimit(10000000)


def ii(): return int(sys.stdin.buffer.readline().rstrip())
def il(): return list(map(int, sys.stdin.buffer.readline().split()))
def fl(): return list(map(float, sys.stdin.buffer.readline().split()))
def iln(n): return [int(sys.stdin.buffer.readline().rstrip())
                    for _ in range(n)]


def iss(): return sys.stdin.buffer.readline().decode().rstrip()
def sl(): return list(map(str, sys.stdin.buffer.readline().decode().split()))
def isn(n): return [sys.stdin.buffer.readline().decode().rstrip()
                    for _ in range(n)]


def lcm(x, y): return (x * y) // math.gcd(x, y)


# MOD = 10 ** 9 + 7
MOD = 998244353
INF = float('inf')


def main():
    if os.getenv("LOCAL"):
        sys.stdin = open("input.txt", "r")

    D, W = il()
    power = [0.24, 1.54, 3.34, 5.44, 7.94, 10.74,
             13.84, 17.14, 20.74, 24.44, 28.44, 32.64]
    direction = [112, 337, 562, 787, 1012, 1237, 1462, 1687,
                 1912, 2137, 2362, 2587, 2812, 3037, 3262, 3487, 3600]
    d = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
         'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N']
    p = bisect.bisect_left(power, W/60)

    if p == 0:
        print('C', 0)
    else:
        print(d[bisect.bisect_left(direction, D)], p)


if __name__ == '__main__':
    main()

考え方

基本的には指示通りの方向と風力を出力するだけですが、
風力は小数点の誤差に気を付ける必要があります。

風力の計算はW/60の値から小数点第2で四捨五入した値を使用します。
そのため、小数点の丸め誤差や、W = 15, W/60 = 0.25のとき風力を1にしなければならないなど、
考える必要があります。

回答例では愚直に風力の値が切り替わる範囲の配列と、
方角が切り替わる値の範囲の配列を作り、
与えられた値がどの位置に属するかを二分探索で求めて回答しました。