ABC181 D - Hachi
備忘録
問題
回答
import sys import os import math import bisect import itertools import collections import heapq import queue import array import time # 時々使う # from scipy.sparse.csgraph import csgraph_from_dense, floyd_warshall # from decimal import Decimal # 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 INF = float('inf') def main(): if os.getenv("LOCAL"): sys.stdin = open("input.txt", "r") S = iss() s_cnt = collections.Counter(S) if len(S) == 1: if S[0] == '8': print('Yes') else: print('No') elif len(S) == 2: for i in range(1, 13): q_cnt = collections.Counter(str(i * 8)) if s_cnt == q_cnt: print('Yes') exit() else: print('No') else: for i in range(13, 125): q_cnt = collections.Counter(str(i * 8)) for k, v in q_cnt.items(): if s_cnt[k] < v: break else: print('Yes') exit() else: print('No') if __name__ == '__main__': main()
考え方
文字列S
が1桁、2桁、3桁以上の3パターンを場合分けして考えます。
- 回答概要
- 文字列
S
が「1桁」「2桁」「3桁以上」の3パターンを場合わけして考える - 「3桁以上」の場合、探索範囲は1000以下の8の倍数のみで良い
- 文字列
まず文字列S
が1桁の場合の時を考えます。
文字列S
は1, 2, 3, ... , 9
のいずれかです。
つまり、文字列S
が8
の場合のみ、Yes
となります。
次に文字列S
が2桁の場合を考えます。
上記の回答では100以下の8の倍数全てに対して、作れるか否かを判定していますが、
これは、無駄な処理です。
文字列S
が2桁であれば、元の文字列と前後を入れ替えた文字列のどちらかが、
8で割り切れるか否かを判定するだけで良いです。
次に文字列S
が3桁以上の場合を考えます。
8 * 125 = 1000
であることから、
10 ** 4
も10 ** 5
も8の倍数であることがわかります。
このことから、下3桁が8の倍数であれば、
それ値は8の倍数であることがわかります。
そのため、与えられた文字列S
から3桁の8の倍数を作ることができれば、
文字列を入れ替えて8の倍数を作ることが可能であると判定できます。