ごり〜
こんばんは
前回のABC-376 のBやFで、円環を扱う問題が出ましたね
ゴリはB問題の段階で頭を使いたくないな〜と思った挙句に実際に時計回り/反時計回りにwhileで回す というパワープレイでどうにかACを取りました
が、それでも11分ぐらいかかっちゃったので、あんまり頭を使わない方法を考えていました
TLで 円環ライブラリ を作った、とかの声をちらほら見た気がして、どういうのがあれば楽だったんだろうと自分なりにも考えてみました
それを残します
RingCalculator
というのを作りました。
ごりちゃんライブラリにあげてあります →こちら
使い方なども↑を参照して欲しいのですが、
dist_clockwise(x,y) で、xからyまで時計回りで回ったときの距離、
dist_anticlockwise(x,y) で、xからyまで反時計回りで回ったときの距離
がそれぞれ求まるようにしています。
これがあると例えば、xからみて時計回りでyの方がzよりも近いか?(xからyまでの時計回りの中にzが含まれていないか?) を以下のように判定することができます
rc.dist_clockwise(x,y) < rc.dist_clockwise(x,z)
そして、ABC376-B は以下のコードでACできます。提出
何気に1-indexed にも対応してます (デフォルトは0-indexed)
# https://github.com/prd-xxx/gorichan_kyopro_library/blob/main/ring_calculator/ring_calculator.py class RingCalculator: def __init__(self, size, base_index=0): self.size = size self.base_index = base_index def _normalize(self, index): return (index - self.base_index) % self.size def dist_clockwise(self, from_index, to_index): fr = self._normalize(from_index) to = self._normalize(to_index) return (to - fr) % self.size def dist_anticlockwise(self, from_index, to_index): return (self.size - self.dist_clockwise(from_index, to_index)) % self.size N,Q = map(int,input().split()) HT = [input().split() for i in range(Q)] rc = RingCalculator(N,base_index=1) ans = 0 l,r = 1,2 for h,t in HT: t = int(t) if h=='L': if rc.dist_clockwise(l,t) < rc.dist_clockwise(l,r): ans += rc.dist_clockwise(l,t) else: ans += rc.dist_anticlockwise(l,t) l = t else: if rc.dist_clockwise(r,t) < rc.dist_clockwise(r,l): ans += rc.dist_clockwise(r,t) else: ans += rc.dist_anticlockwise(r,t) r = t print(ans)
おわり
これだけでした
ちょっとしたコードだけど多分次使うときにはありがたみを感じてると信じたい!