読者です 読者をやめる 読者になる 読者になる

君はまるで砂漠に咲く、一輪の花。

僕はその花に引き寄せられる蝶。

Codeforces Round #307 (Div.2)

はい。
http://codeforces.com/contest/551

A. GukiZ and Contest

ざっくりと大意

・n人の学生がプログラミングコンテストで\(a_i\)のレーティングを得た??
・それぞれの学生が何番目の成績であるかを出力する??

方針のようなもの

・成績のいい方から調べる。

python

n=int(raw_input())
a=map(int,raw_input().split())

chk=a[:]
chk.sort()
chk=chk[::-1]
ans=[]
for i in a:
    ans.append(str(chk.index(i)+1))
print ' '.join(ans)

lambdaとか使うともっと短く書けるらしい。。

B. ZgukistringZ

ざっくりと大意

・文字列aを並び替えて文字列bかc最も多い回数を含んでいるように並び替える??
・例えばbを2回とcを1回のパターンと、bを3回とcを0回とではどちらも同等に合計3回の出現回数なので最多3回ならどちらでもよい。

方針のようなもの

・全部調べる。

python

a=raw_input()
b=raw_input()
c=raw_input()

def cnt(x):
    l=[0]*26
    for i in x:
        l[ord(i)-97]+=1
    return l

def mini(x,y):
    m=10000001
    for i in range(26):
        if y[i]>0 and x[i]/y[i]>0:
            m=min(m,x[i]/y[i])
        elif y[i]>0 and x[i]/y[i]==0:
            return 0
    return m if m!=10000001 else 0

def use(p,q,r):
    for i in range(26):
        p[i]-=q[i]*r
    return p

cntA=cnt(a)
rep=cntA[:]
cntB=cnt(b)
cntC=cnt(c)

chk=[0,0]

chk[0]=mini(cntA,cntB)
cntA=use(cntA,cntB,chk[0])

chk[1]=mini(cntA,cntC)
cntA=use(cntA,cntC,chk[1])

ans=[(sum(chk), chk[0],chk[1])]
for i in range(chk[0]):
    for j in range(26):
        cntA[j]+=cntB[j]
    k=mini(cntA,cntC)
    for t in range(26):
        cntA[t]-=cntC[t]*k
    lst=[ans[-1][1]-1,ans[-1][2]+k]
    ans.append((sum(lst),lst[0],lst[1]))

ans.sort()
w=b*ans[-1][1]+c*ans[-1][2]
for i in range(26):
    rep[i]-=(cntB[i]*ans[-1][1]+cntC[i]*ans[-1][2])
    if rep[i]>0:
        w+=chr(i+97)*rep[i]
print w

過去に解いたことがある割にはもう一度やってみると上手く書けず。。しかも変数名が被ってたりとかif文の判定がおかしかったり、二重ループの内側でjを使うはずがiをつかったり酷いミスで無駄にWA。。まぁ悪い間違え方、見直しポイントのノウハウが集まったと前向きに。。 回答の方針としては最初にはbを使える限りと余りでcの個数を見た後に、bを1つずつ戻してcを増やせるなら増やすという風にしてb,c合計の最大にある使い方を探すようにした。