Processing math: 100%

2021年8月5日木曜日

2021 TCO Algo Regional Qualification 1

  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みたいにしてしまっていた。

 焦っていたとはいえ良くない間違いでした。

 システムテストを通ったコードです。
 
  1. mod=1000000007
  2.  
  3. class TreeTokens ():
  4. def placeMax(self, N, G, L, seed):
  5. state = seed
  6. E=[[] for i in range(N)]
  7. for i in range(1,N):
  8. state = (state * 1103515245 + 12345) % (1<<31)
  9. tmp = (state // 1000) % L
  10. p = max(0, i-1-tmp)
  11.  
  12. E[i].append(p)
  13. E[p].append(i)
  14.  
  15. #print(E)
  16.  
  17. ROOT=G
  18.  
  19. QUE=[ROOT]
  20. Parent=[-1]*(N+1)
  21. Parent[ROOT]=N # ROOTの親を定めておく.
  22. TOP_SORT=[] # トポロジカルソート
  23.  
  24. while QUE: # トポロジカルソートと同時に親を見つける
  25. x=QUE.pop()
  26. TOP_SORT.append(x)
  27. for to in E[x]:
  28. if Parent[to]==-1:
  29. Parent[to]=x
  30. QUE.append(to)
  31.  
  32.  
  33. CC=[-1]*N
  34.  
  35. for x in TOP_SORT[::-1][:-1]:
  36. if CC[x]==-1:
  37. CC[x]=1
  38. if Parent[x]==ROOT:
  39. continue
  40. CC[Parent[x]]=max(CC[Parent[x]],CC[x]+1)
  41.  
  42.  
  43.  
  44. AC=[0]*N
  45. AC[ROOT]=0
  46. ANS=0
  47.  
  48. QUE=[ROOT]
  49. while QUE:
  50. x=QUE.pop()
  51.  
  52. MAX=-1
  53. if len(E[x])==1 and x!=ROOT:
  54. ANS+=AC[x]
  55. ANS%=mod
  56. for to in E[x]:
  57. if to==Parent[x]:
  58. continue
  59. MAX=max(CC[to],MAX)
  60.  
  61. USE=0
  62. for to in E[x]:
  63. if to==Parent[x]:
  64. continue
  65. if CC[to]==MAX and USE==0:
  66. USE=1
  67. AC[to]=(AC[x]*2+1)%mod
  68. else:
  69. AC[to]=1
  70.  
  71. QUE.append(to)
  72. return ANS%mod

0 件のコメント:

コメントを投稿