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にすれば辻褄が合うことが分かる。

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

class EpicPartition():
    def createPartition(self, N):

        if N%4!=0:
            return ""

        k=N*6
        ALL=k*(k+1)//2
        CK=(ALL//2)//(k//3)

        ANS=["a"]*k
        ANS[-1]="c"
        for i in range(CK-k//6,CK+k//6-1):
            ANS[i]="c"

        f=0
        for i in range(k):
            if f< k//3 and ANS[i]!="c":
                if f%2==0:
                    ANS[i]="a"
                else:
                    ANS[i]="b"
                f+=1

            elif ANS[i]!="c":
                if f%2==1:
                    ANS[i]="a"
                else:
                    ANS[i]="b"
                f+=1

        return "".join(ANS)

0 件のコメント:

コメントを投稿