Processing math: 0%

2020年7月10日金曜日

Kick Start Round A 2020

 Dが解けず。
 コンテスト中もTrie木を使うのかな、とは思ったようですが……。

コンテストへのリンク
コンテスト後のツイート

Bundling

 (英語だけど)この動画解説を参考にした。……けど、Trieが頭に入っていればそれほど難しくないね。簡単な木DPで解けます。

 Trieについては、kami634さんの記事が詳しいし分かりやすい。上の動画でTrieの概要は理解できたのだけど、実装をどうすれば良いか分からなくなったときこの記事が参考になった。感謝。
 実装方針が分かってしてしまえば意外と書くのは簡単だったけれど、自分で最初実装を考えたときは、辞書を使って云々しなくてはいけない気がしてしまい困った。ノードが追加されるたびに、新しいidを割り当てるようにすれば良いですね。

 ACした提出を一応載せておきます。(見ての通り、Trieをclassにしたりはしてません)

  1. import sys
  2. input = sys.stdin.readline
  3.  
  4. T = int(input())
  5. for testcases in range(T):
  6. N,K=map(int,input().split())
  7.  
  8. # Trie木
  9.  
  10. Next_node_id=[[-1]*26] # "A"~"Z"それぞれについて、対応する次のノードのid
  11. Parent_id=[-1] # 親ノード
  12. Depth=[0] # Trieのノードの深さ
  13. Count=[0] # Trieのノードの重複度
  14.  
  15. Nodes_id=1 # 以下、標準入力で与えられたN個の文字列を追加する実装
  16. for i in range(N):
  17. S=input().strip()
  18. L=len(S)
  19.  
  20. NOW=0
  21. for s in S:
  22. NEXT=ord(s)-65
  23. if Next_node_id[NOW][NEXT]==-1: # Nodeを追加する場合
  24. Next_node_id[NOW][NEXT]=Nodes_id
  25.  
  26. Next_node_id.append([-1]*26)
  27. Parent_id.append(NOW)
  28. Depth.append(Depth[NOW]+1)
  29. Count.append(0)
  30.  
  31. NOW=Nodes_id
  32. Nodes_id+=1
  33.  
  34. else: # 追加しない場合
  35. NOW=Next_node_id[NOW][NEXT]
  36.  
  37. Count[NOW]+=1 # 終端に印を付ける
  38.  
  39. TOP_SORT=sorted([(dep,id) for id,dep in enumerate(Depth)],reverse=True)
  40.  
  41. Rest=[0]*len(TOP_SORT)
  42. ANS=0
  43.  
  44. for dep,n in TOP_SORT:
  45. c=Count[n]+Rest[n]
  46. ANS+=Depth[n]*(c//K)
  47. Rest[Parent_id[n]]+=c%K
  48.  
  49. print("Case #"+str(testcases+1)+": "+str(ANS))
  50.  

0 件のコメント:

コメントを投稿