CODE THANKS FESTIVAL 2018の解説
A - Two Problems
入力:
制約:
出力: 高橋君の取りうる最大の得点
分かけて点
分かけて点 とれます。
それで、分の時間があります。
になっているので、まずは分かけて点取れないかを調べて、次に分かけて点とれないかどうかを判定すればよいです。
ulong res; if(T - C >= 0) { T -= C; res += D; } if(T - A >= 0) { res += B; } res.writeln;
感想: 普通のA問題。
B - Colored Balls
入力:
出力: 箱を空にできるなら'Yes'、そうでないなら'No'
制約:
とを比較して、小さい方は3を引き、大きい方からは1を引く操作を繰り返します。になったら、'Yes'を出力します。
操作の途中で、になってしまったら、'No'を出力すればよいです。
bool flag = true; while(flag) { if(X == 0 && Y == 0) { writeln("Yes"); return; } if(X > Y) { if(X - 3 >= 0 && Y - 1 >= 0) { X -= 3; Y--; } else flag = false; } else { if(Y - 3 >= 0 && X - 1 >= 0) { Y -= 3; X--; } else flag = false; } } writeln("No");
感想: 3WA。変に難しいことをしないで、単純に処理を書いたらACできた。
C - Pair Distance
入力:
出力: この街の交流コスト
制約:
は全て異なる
単純に必要なコストを計算すると、となり、最悪の場合にとなってしまい間に合わなくなってしまうかもしれません。
そこで、少し工夫を加えてみます。
まず、与えられたリストをソートします。そうすると、で計算されていたコストを、としてで計算できるようになります。
それと、は負の値もとりますが、後々の計算で不都合が生じるので、リストの最小値をリストのそれぞれの要素から引いておきます(そうすると最小値が0に揃い、計算するときに負の値を考慮しなくてよくなります)。
また、愚直に計算をするとTLEするので、累積和を使います。
とすると、交流コストはのとき
のようになります。
一般化すると、
のようになります。
これによって、で計算することができました。
auto N = readln.chomp.to!int; auto x = readln.split.to!(long[]).sort().array; auto m = x.reduce!min; x = x.map!(i => i - m).array; long[] arr = new long[](N); arr[0] = x[0]; foreach(i; 1..N) { arr[i] = arr[i-1] + x[i]; } ulong res; foreach_reverse(i; 1..N) { res += i*x[i] - arr[i-1]; } res.writeln;
感想: ちょっと難しい問題だった。
D - Concatenation
入力:
出力: 連結してになるような題意の文字列の個数の最小値
制約:
は英小文字からなる
「連結」とは、今ある文字列の末尾に新たに文字列をつなげることです。
与えられた文字列を先頭から一つずつ見ていきます。
元となるそれぞれの文字列には、先頭と同じ文字が複数含まれていない、とのことであるから、これと「先頭の文字がその文字列においてアルファベット順で最小」より「先頭の文字と同じまたはアルファベット順でそれより小さい文字」があった場合には新たな文字列を繋げる必要があります。
dchar now = S[0]; ulong cnt = 1; foreach(i; S[1..$]) { if(now >= i) { cnt++; now = i; } } cnt.writeln;
感想: これ絶対Cより簡単だった。200点で出てもおかしくなさそう。