SRM 563 DIV1 Easy - FoxAndHandle (復習××)

問題


http://community.topcoder.com/stat?c=problem_statement&pm=12331&rd=15185

文字列が与えられて、その文字をシャッフルして元の文字にランダムに挿入する。
挿入後の文字列が与えられた時、元の文字列のうち辞書順に最小のものを求める。

解き方


文字の種類については、与えられた各文字を2で割ったものになる。
次に文字の順番については、ひとつ選ぶとその前の文字は選べなくなる。

選ぶべき文字の種類を満たし、かつ辞書順になるよう小さいアルファベットから
上の判定を繰り返していく。

コード


class FoxAndHandle {

public: string lexSmallestName(string S) {
int num[26]={0};
string ans="";

FORE(i,0,S.size())num[S[i]-'a']++;
FORE(i,0,26)num[i]=num[i]/2;

while(accumulate(num,num+26,0)>0){
pair<char,int> best=make_pair('z'+1,-1);
FORE(i,0,S.size()){
if(num[S[i]-'a']==0)continue;

int count[26]={},invalid=0;
FORE(j,i,S.size())count[S[j]-'a']++;
FORE(j,0,26)if(num[j]>count[j])invalid=1;
if(invalid)continue;

best=min(best,make_pair(S[i],i));
}
ans+=best.first;
num[best.first-'a']--;
S=S.substr(best.second+1);
}

return ans;
}

};
このエントリーをはてなブックマークに追加