Easyで誤読&実装方針をミス、解けたと思ったMedはシステムテストで落ちて0完。青に落ちてしまった。
OlympicShooting
これは読解&実装問題。
・スコアの合計が高い方が勝ち
・同じなら、後ろから順に、25回ずつのスコアが高い方が勝ち。
・それも同じなら、より後でスコア獲得した方が勝ち。
というのを実装する。
最初、「25回ずつ」というのを読み飛ばして戸惑った。
その後、上手い実装がないかと考えていたのが失敗(とはいえ、短くコードをまとめている人もいた)。多少時間がかかっても愚直に書けば良かった。
TreeTokens
解法はすぐに分かり、それであっていたが実装でミスしてしまった。
ROOTに駒がこないためには、ROOTの隣は1個しかあってはダメ。じゃあ、その隣は、というと、3個までしかあってはダメ。その隣は7個まで。さらにその隣は15個まで。
つまり、ある頂点の駒が高々i個になるためには、その隣の頂点での駒は高々2*i+1個であれば良い。問題が直線状で、ROOTが端にあれば、N=(頂点数-1)として、2^N-1個が答えになる。
では分岐があったときは? というと、葉が深い方の枝に駒を増やしていく(2*i+1倍していく)のが最善。もう一つの分岐は、駒1個からまた増やしていく。
そういう感じで、各頂点について「葉までの距離のmax」を前計算した後、ROOTの方がから木DPをしていく感じに解いた。
……のだが、「葉までの距離のmax」の前計算する箇所で間違えた。
これはよくある木DPなので、トポロジカルソートの逆順に見ていけば良いのだが、なぜかDFSみたいにしてしまっていた。
焦っていたとはいえ良くない間違いでした。
システムテストを通ったコードです。
mod=1000000007 class TreeTokens (): def placeMax(self, N, G, L, seed): state = seed E=[[] for i in range(N)] for i in range(1,N): state = (state * 1103515245 + 12345) % (1<<31) tmp = (state // 1000) % L p = max(0, i-1-tmp) E[i].append(p) E[p].append(i) #print(E) ROOT=G QUE=[ROOT] Parent=[-1]*(N+1) Parent[ROOT]=N # ROOTの親を定めておく. TOP_SORT=[] # トポロジカルソート while QUE: # トポロジカルソートと同時に親を見つける x=QUE.pop() TOP_SORT.append(x) for to in E[x]: if Parent[to]==-1: Parent[to]=x QUE.append(to) CC=[-1]*N for x in TOP_SORT[::-1][:-1]: if CC[x]==-1: CC[x]=1 if Parent[x]==ROOT: continue CC[Parent[x]]=max(CC[Parent[x]],CC[x]+1) AC=[0]*N AC[ROOT]=0 ANS=0 QUE=[ROOT] while QUE: x=QUE.pop() MAX=-1 if len(E[x])==1 and x!=ROOT: ANS+=AC[x] ANS%=mod for to in E[x]: if to==Parent[x]: continue MAX=max(CC[to],MAX) USE=0 for to in E[x]: if to==Parent[x]: continue if CC[to]==MAX and USE==0: USE=1 AC[to]=(AC[x]*2+1)%mod else: AC[to]=1 QUE.append(to) return ANS%mod
0 件のコメント:
コメントを投稿