コンテスト中もTrie木を使うのかな、とは思ったようですが……。
コンテストへのリンク
コンテスト後のツイート
Bundling
(英語だけど)この動画解説を参考にした。……けど、Trieが頭に入っていればそれほど難しくないね。簡単な木DPで解けます。
Trieについては、kami634さんの記事が詳しいし分かりやすい。上の動画でTrieの概要は理解できたのだけど、実装をどうすれば良いか分からなくなったときこの記事が参考になった。感謝。
実装方針が分かってしてしまえば意外と書くのは簡単だったけれど、自分で最初実装を考えたときは、辞書を使って云々しなくてはいけない気がしてしまい困った。ノードが追加されるたびに、新しいidを割り当てるようにすれば良いですね。
ACした提出を一応載せておきます。(見ての通り、Trieをclassにしたりはしてません)
- import sys
- input = sys.stdin.readline
- T = int(input())
- for testcases in range(T):
- N,K=map(int,input().split())
- # Trie木
- Next_node_id=[[-1]*26] # "A"~"Z"それぞれについて、対応する次のノードのid
- Parent_id=[-1] # 親ノード
- Depth=[0] # Trieのノードの深さ
- Count=[0] # Trieのノードの重複度
- Nodes_id=1 # 以下、標準入力で与えられたN個の文字列を追加する実装
- for i in range(N):
- S=input().strip()
- L=len(S)
- NOW=0
- for s in S:
- NEXT=ord(s)-65
- if Next_node_id[NOW][NEXT]==-1: # Nodeを追加する場合
- Next_node_id[NOW][NEXT]=Nodes_id
- Next_node_id.append([-1]*26)
- Parent_id.append(NOW)
- Depth.append(Depth[NOW]+1)
- Count.append(0)
- NOW=Nodes_id
- Nodes_id+=1
- else: # 追加しない場合
- NOW=Next_node_id[NOW][NEXT]
- Count[NOW]+=1 # 終端に印を付ける
- TOP_SORT=sorted([(dep,id) for id,dep in enumerate(Depth)],reverse=True)
- Rest=[0]*len(TOP_SORT)
- ANS=0
- for dep,n in TOP_SORT:
- c=Count[n]+Rest[n]
- ANS+=Depth[n]*(c//K)
- Rest[Parent_id[n]]+=c%K
- print("Case #"+str(testcases+1)+": "+str(ANS))
0 件のコメント:
コメントを投稿