はじめに
@drkenさんの記事である「AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~」にはPHPの解答はないので、類題も含めてPHPで解いてみました。
※筆者はPHP初心者なので、解答は決してきれいなものではないです。
リファクタリングもしておらず、実際に一番最初に書いて、正解となったコードを載せています。
その点はご了承ください
また、こういう解き方もあるよ!という方は、優しくコメントで教えていただけますと幸いです
まず、解いてみよう!
試行錯誤しよう
「よし、解き方がわからなかったからちょうどよかった。どれどれ、答えは?」
と思ったそこのあなた!
とにかく、もう30分だけ粘ってみてください!
「こうしてみたらどうかな?だめかー。じゃあこれならどうだ!これもだめかー。これはいけるだろ!だめかー。」
というように、「try and error」を繰り返してみてください。
そうする中で、もし解けたら万々歳です。
もし解けなかったとしても、まったく気にしません。むしろ、学習という面から考えると、解けないことの方が大事だと思います。
なぜなら、今持っている自分の知識をフル活用しても解けなかったということは、新たな知識を得られるということだからです!
ハッピーハッピーハッピー!ですね!(猫ミームより)
調べよう
「やっと、答え見れるわ~」
と思ったそこのあなた!
まだ解答にたどり着くには早いです。
次は、一通り試行錯誤した上で、どうやったら解けるか調べていきましょう!
筆者はいつも次の流れで調べています。
- わからないことについて、単語を羅列して検索をかける
- 記事などで大体のイメージをつかむ
- 公式リファレンスから正しい知識をインプットする
この流れに沿って調べながら、もう一度問題を解いていきましょう。
これで、ほとんどの問題は解けると思います。
しかし、悲しいかな、マジで解けない時もあります。
そういう時は、素直に解答を見ましょう。
そして、何も見ずに書けるまで、何度も繰り返し書きましょう。
解答
第1問: ABC 086 A - Product (100点)
<?php
fscanf(STDIN, "%d %d", $b, $c);
$result = $b * $c;
if ($result % 2 === 0) {
echo 'Even' . PHP_EOL;
} elseif ($result % 2 === 1) {
echo 'Odd' . PHP_EOL;
}
類題
- ABC 064 A - RGB Cards (同じく倍数判定です)
<?php
fscanf(STDIN, "%d %d %d", $a, $b, $c);
(int) $result = $a . $b . $c;
if ($result % 4 === 0) {
echo 'YES' . PHP_EOL;
} elseif ($result % 4 !== 0) {
echo 'NO' . PHP_EOL;
}
- ABC 088 A - Infinite Coins (倍数判定の発展として、余りを計算します)
<?php
fscanf(STDIN, "%d", $a);
fscanf(STDIN, "%d", $b);
$result = $a % 500;
if ($result <= $b) {
echo 'Yes' . PHP_EOL;
} elseif ($result > $b) {
echo 'No' . PHP_EOL;
}
- ABC 157 A - Duplex Printing (余りを切り上げる処理をします)
<?php
$a = trim(fgets(STDIN));
const PAGE = 2;
$result = ($a + PAGE - 1) / PAGE;
$result = floor($result);
echo $result . PHP_EOL;
第 2 問: ABC 081 A - Placing Marbles (100 点)
<?php
echo substr_count(fgets(STDIN), 1) . PHP_EOL;
類題
- ABC 095 A - Something on It (非常によく似た問題です)
<?php
$topping = substr_count(fgets(STDIN), 'o');
echo 700 + ($topping * 100) . PHP_EOL;
- ABC 085 A - Already 2018 (string 型を扱う練習です)
<?php
$date = fgets(STDIN);
$replacedDate = substr_replace($date, '8', 3, 1);
echo $replacedDate;
- ABC 069 B - i18n (B 問題ですが for 文不要で難しくなく、string 型を扱うよい練習問題です)
<?php
$vocabulary = fgets(STDIN);
$num = strlen($vocabulary) - 3;
$replacedVoc = substr_replace($vocabulary, $num, 1, -2);
echo $replacedVoc;
- ABC 082 B - Two Anagrams (辞書順最小に関する理解を問います、B 問題なので少し難しくなります、下に出て来るソートも使います)
<?php
$s = trim(fgets(STDIN));
$t = trim(fgets(STDIN));
$s_sorted = str_split($s);
$t_sorted = str_split($t);
sort($s_sorted);
rsort($t_sorted);
if (implode('', $s_sorted) < implode('', $t_sorted)) {
echo "Yes" . PHP_EOL;
} else {
echo "No" . PHP_EOL;
}
第 3 問: ABC 081 B - Shift Only (200 点)
<?php
$n = fgets(STDIN);
$a = explode(" ", fgets(STDIN));
$min = 100;
for ($i = 0; $i < $n; $i++) {
for ($j = 0; $a[$i] % 2 === 0; $j++) {
$a[$i] /= 2;
}
$min = min($j, $min);
}
echo $min . PHP_EOL;
類題
- ABC 068 B - Break Number (例題によく似た問題です)
<?php
$n = intval(trim(fgets(STDIN)));
$max_count = 0;
$result = 1;
for ($i = 1; $i <= $n; $i++) {
$num = $i;
$count = 0;
while ($num % 2 == 0) {
$num /= 2;
$count++;
}
if ($count > $max_count) {
$max_count = $count;
$result = $i;
}
}
echo $result . PHP_EOL;
- ABC 102 B - Maximum Difference (できれば for 文を 1 回だけ使って解いてみましょう)
<?php
$n = fgets(STDIN);
$a = explode(" ", fgets(STDIN));
$result = 0;
$max_abs = 0;
for ($i = 0; $i < $n; $i++) {
for ($j = 0; $j < $n - ($i + 1); $j++) {
$abs = abs($a[$i] - $a[$i + $j + 1]);
if ($max_abs < $abs) {
$max_abs = $abs;
}
}
}
echo $max_abs . PHP_EOL;
- ABC 113 B - Palace (最小値を求めるだけでなく、最小になる index を求める書き方も確認しましょう)
<?php
$n = fgets(STDIN);
$ta = explode(" ", fgets(STDIN));
$h = explode(" ", fgets(STDIN));
$t = $ta[0];
$a = $ta[1];
$mostNearA = 10000;
$result = '';
for ($i = 0; $i < $n; $i++) {
$TemperatureAvg = $t - $h[$i] * 0.006;
$abs = abs($a - $temperatureAvg);
if ($mostNearA > $abs) {
$mostNearA = $abs;
$result = $i + 1;
}
}
echo $result . PHP_EOL;
- ABC 072 B - OddString (文字列に対する for 文も、数列に対する for 文と同様です)
<?php
$string = trim(fgets(STDIN));
$result = '';
for ($i = 0; $i < strlen($string); $i += 2) {
$result .= $string[$i];
}
echo $result . PHP_EOL;
- ABC 053 B - A to Z String (同じく文字列に対する for 文です)
<?php
$s = trim(fgets(STDIN));
$start = strpos($s, 'A');
$end = strrpos($s, 'Z');
$result = $end - $start + 1;
echo $result . PHP_EOL;
- ABC 095 B - Bitter Alchemy (max や sum といった、for 文テクニックの総動員です)
<?php
fscanf(STDIN, "%d %d", $n, $x);
while ($input = trim(fgets(STDIN))) {
$M[] = $input;
}
$i = 0;
foreach ($M as $m) {
$x = $x - $m;
$i++;
}
$min = min($M);
while ($x >= $min) {
$x = $x - $min;
$i++;
}
echo $i . PHP_EOL;
第 4 問: ABC 087 B - Coins (200 点)
<?php
$a = fgets(STDIN);
$b = fgets(STDIN);
$c = fgets(STDIN);
$x = fgets(STDIN);
$result = 0;
for ($i = 0; $i <= $a; $i++) {
for ($j = 0; $j <= $b; $j++) {
for ($k = 0; $k <= $c; $k++) {
if ($i * 500 + $j * 100 + $k * 50 == $x) {
$result++;
}
}
}
}
echo $result . PHP_EOL;
大変申し訳ありません。
筆者がここまでしか解いていないので、今回はここまでです。
随時更新していきます!