Processing math: 100%

2020年7月3日金曜日

TopCoder Single Round Match 781

 EasyをHackされて0完でした。
 いや、これは解けなくちゃいけない問題でしたね。こういう、それほど難しくない構築は取りたい……。

Div1 Easy EpicPartition


 公式解説を読むと、色々方法がある、と書いてある(としか書いてない)。kmjpさんの解説もあるけど、色々な方法があるらしいので、別な方法を考えた。

 cの位置を決めることを考える。
 kmjpさんの解説にもある通り、cを埋めた残りが全て二個連続していれば(適当な四個を前半二個、後半二個に分けて)"abba"とすることで、aとbの和を一致させることができる。
 なので、できるだけ連続している位置にcを埋めたい。

 ここで、"c"を埋め込むときの平均値を考える。
 たとえば、N=6のとき、全体の和は300、"c"の和は150で8個なので、平均は18.75。なので、18と19を中心に、15~22を"c"にしようとすると2だけ不足する。のえ、最後の22を24に変えれば辻褄が合う。

 一般にこういう構成で良いことは立式すれば証明できる(できた)。
 1~24xの中から1/3を"c"にするとすると、"c"の和は144x^2+6xで、18.5x中心に構成した和は144x^2+4x。後者の構成の最大の数は18x+4xなので、それを1~24xの中で最大の数である24xにすれば辻褄が合うことが分かる。

 以下、システムテストを通ったコード。

  1. class EpicPartition():
  2. def createPartition(self, N):
  3.  
  4. if N%4!=0:
  5. return ""
  6.  
  7. k=N*6
  8. ALL=k*(k+1)//2
  9. CK=(ALL//2)//(k//3)
  10.  
  11. ANS=["a"]*k
  12. ANS[-1]="c"
  13. for i in range(CK-k//6,CK+k//6-1):
  14. ANS[i]="c"
  15.  
  16. f=0
  17. for i in range(k):
  18. if f< k//3 and ANS[i]!="c":
  19. if f%2==0:
  20. ANS[i]="a"
  21. else:
  22. ANS[i]="b"
  23. f+=1
  24.  
  25. elif ANS[i]!="c":
  26. if f%2==1:
  27. ANS[i]="a"
  28. else:
  29. ANS[i]="b"
  30. f+=1
  31.  
  32. return "".join(ANS)

0 件のコメント:

コメントを投稿