TopCoder SRM 385 Div1 Easy UnderscoreJustification
問題
n個の単語を、幅w文字になるよう単語と単語の間に"_"を入れて一行に書きたい。
それぞれの単語と単語の間の"?"の数はなるべく均等になるようにしたい。
(すなわち、最も多い"_"と最も少ない"_"の差が1以下になるようにしたい)
それが複数ある場合、辞書順で最小になるものを選ぶ。
"_"を入れて、単語を幅wになるように並べて書いたものを出力せよ。
先頭の単語の前および、最後の単語の後ろには"_"を入れることはできない。
また、"_"は文字コードで、大文字よりも後に来て、小文字よりも前に来る。
制約条件
n≦10
w≦200
方針
greedy.
入れるべきスペースの数をmとすると、
m/(n-1)個ずつ単語間にスペースを入れるのはきまっていて、
残りのm%(n-1)個をどこに入れるかが問題になる。
これは、なるべく小文字の単語の前で、
次に大文字の単語の前に入れるように貪欲に選べばいい。
小文字の単語は、前にあるものから順に優先的に、大文字の単語は後ろにあるものから優先的に前にスペースを入れる。
ソースコード
class UnderscoreJustification { public: string justifyLine(vector <string> words, int width) { int n=words.size(); vi sml,big,spc(n-1); for(int i=1;i<n;i++)if(islower(words[i][0]))sml.pb(i); else big.pb(i); reverse(all(big)); sml.insert(sml.end(),all(big)); rep(i,n)width-=words[i].size(); rep(i,width%(n-1))spc[sml[i]-1]++; stringstream ss; ss<<words[0]; rep(i,n-1){ rep(j,spc[i]+width/(n-1))ss<<"_"; ss<<words[i+1]; } return ss.str(); } };