こんにちは、くのへです!
2024年8月24日(土)にScratchで競技プログラミングに挑戦!という講座を実施し、その中で「AtCoder最初の10問」というテーマの1問目をScratchで解くところまで習得しますので、それについて記事にしました。
また、「AtCoder最初の10問」の各問題のScratchでの回答例を載せました。
ただし「AtCoder最初の10問」の詳細解説までをこのページに載せると、記事サイズが大きくなってしまうので、この記事では、概要とScratchの解法リンクのみを載せました。時間があれば各詳細も記事化したいと考えています。
なお、ファーストゲートの講座では「そもそもAtCoderとは?」や「VBA(厳密にはVB.NET),Python,GAS(厳密にはJavaScript)で解く方法」についても解説しますが、本記事では割愛しています。
Scratchで競技プログラミング(AtCoder)に挑戦する方法
まず、次のページを訪れてChromeの拡張機能「Scratcher’s AtCoder」をChromeに追加します。
(EdgeでもChromeウェブストアの拡張機能をインストールできます)
https://chromewebstore.google.com/detail/scratchers-atcoder/hackndbjgkehhjinjjoldifbhnfddklh
そしてAtCoderのコード記述欄を見ると、、、今までなかったボタンがある!!
そう、この「Scratch 3.0 プロジェクトをロード」ボタンを使って、Scratchで作成したプログラム(.sb3ファイル)をアップロードすることで、ScratchでAtCoderに挑戦できるようになります。
ただし、言語設定はc++14以上のバージョンを選択する必要があります。
これで準備はOKです!!
まずは Welcome to AtCoderをScratchで解こう
初めてAtCoderに挑戦する方は必ず通る「Welcome to AtCoder」をScratchで解いてみましょう。
問題文は以下の通りですね。
高橋君はデータの加工が行いたいです。
整数 a,b,cと、文字列 s が与えられます。 a+b+c の計算結果と、文字列 s を並べて表示しなさい。
【制約】
1≤∣s∣≤100
1≤a,b,c≤1,000
【入力】
入力は以下の形式で与えられる。
a
b c
s
【出力】
a+b+c と s を空白区切りで 1 行に出力せよ
【入力例 1】
1
2 3
test
【出力例 1】
6 test
まず、Scratchで入力を取得するには、「〇と聞いて待つ」を使います。
そして、「答え」を変数に格納します。
これで、1つ目の入力を取得できます。
同じように変数を作って繰り返すことで、全ての入力を取得できます。
ポイントはScratchでは改行区切り・空白区切りは区別なく、1入力ずつ「〇と聞いて待つ」を使って取得するという点です。
VB.NETやJavaScript、Pythonなどは、1行ごともしくはinputを丸ごと取得して、Split等でバラバラにしてから使用するので、ここは大きく異なる点です。
そして、出力(回答)は「〇と言う」のブロックを使います。
今回は「a+b+c」「空白スペース」「S」を1行で返す、という課題ですので、次のコードを作ればOKです。
(なお、文字列を繋ぎ合わせるのは、「演算」の中にある「りんごとバナナ」ブロックを使います。)
ここで、a+b+cとSの間に半角スペースを入れる必要があります。ここに半角スペースを入れないと不正解になるので、必ず入力します。
あとは、ファイル⇒コンピューターに保存する、でsb3データをエクスポートしましょう。
これをAtCoderの「Scratch 3.0 プロジェクトをロード」ボタンを押して読み込ませます。
これでC++言語に変換され、一気にコードが書かれます。
これを提出しましょう。
待っていると、AC(Accepted!!正解!!)がでました!!ヨシ!!
なお、この判定の種類は次の通りです。
WJ | AC | WA | TLE | RE | CE |
Waiting for Judging | Accepted | Wrong Answer | Time Limit Exceeded | Runtime Error | Compilation Error |
採点中 | 正解 | 不正解 | タイムオーバー | 実行時エラー | 言語再確認(コンパイル失敗) |
以上がScratchでAtCoderに挑戦する方法をザッと解説したものです。
よく分からなかったらファーストゲートに入塾してください!(宣伝)
最初の10問をScratchで解く方法(リンク集)
記事を書いたらその記事へのリンクを貼っていきます。
それまではScratchへのリンクを貼っておきますので、参考にしてください~
ABC086A – Product
この問題は、偶数か奇数かを判別する問題であり、「〇を〇で割った余り」を使います。
この「〇を〇で割った余り」というロジックは、実際に結構使われています。
例えば、エクセルの条件付き書式にて「行番号を2で割った余りが1の時はセルに色を付ける」と設定すると、表をシマシマにすることが出来ます。
このような交互に処理する、1,2,3,1,2,3,,,のように繰り返し処理するロジックを作る時に使用するロジックですので、ScratchでAtCoderに挑戦して習得したら、将来的にも使える良い課題だと思います。
ABC081A – Placing Marbles
この問題は3文字の文字列を1文字ずつバラバラにして処理させる問題です。
この「文字列を1文字ずつ処理する」というロジックも、割と使われています。
例えばタッチタイピングゲームを作りたい時に「ohayou(おはよう)」と登録しておいた文字列から、1文字ずつ切り出して画面に表示させるということを行います。
シンプルに1文字ずつバラバラにするコードがこちらです。
Scratchの解法例リンク
3文字を繰り返し処理を用いて処理させたコードがこちらです。
Scratchの解法(別解)リンク
ABC081B – Shift only
さあ、この辺りから難しくなってきます。
今までは1問100点でしたが、ここから200点問題に突入です。
問題文もちょっと難しいです。入力例を見て理解しましょう!
この問題は、N個の入力があり、それぞれを処理して回答を取得する必要があります。
「N個」と指定はありますが、その数が決まっているわけではない所がポイントです。
このような入力が不特定多数の場合はScratchではリストを使って解く必要があります。
しかも、今回は「それぞれを2で何回割れるか」「割れる回数の最小値」を求める必要があります。
そのため、リストを使うというプログラム的な難しさと、ロジック的な難しさの両方を兼ね備えた問題になります。
これをお子さんが解けるようなら、プログラミングのレベルという意味でもかなりのレベルに達していると言っていいと思います。
ABC087B – Coins
500 円玉をA枚、100 円玉を B 枚、50 円玉を C枚持っていて、合計金額がX円にする方法は何通りあるか?という問題です。
人間がこれを考えるとXの値を分解してA,B,Cの値を求めたくなります。
しかしそう考えるとかなり複雑な手順になってしまい、プログラムにすることができなくなってしまいます。
ここは、プログラミングの世界なので、総当たりで全部確認しちゃえ!!という考え方にスイッチしましょう。
つまり、3重繰り返し構文を使って、A,B,Cにすべての数値を入れて、Xになるかどうかをチェックさせ、正答パターンの数を数えるという考え方です。
プログラミングの世界ではこのような力技でも全然OKだという意識を与えてくれる良い問題だと思います。
ABC083B – Some Sums
この問題も文字列から1文字ずつ文字を取り出して処理させる問題です。
与えられる値の桁数によって式を変更させる必要があります。
ただし最大でも4桁なので、お子さんが最初に挑戦する際には4重の「もし」(If文)でも良いと思います。
こちらの方がプログラムの可読性が良かったりします。
もしも繰り返し構文を使ってスマートに書きたい場合は、別解の方を見て下さい。
4重の「もし(if文)」で解くパターン
Scratchの解法例リンク
繰り返し構文をを使ってスマートに解いたパターン
Scratchの解法(別解)リンク
ABC088B – Card Game for Two
この問題は、「不特定な数の入力」「ソート」「交互に処理」という複合問題です。
不特定な数の入力はリストで受ける必要があります。リストのいい練習になります。
この問題のポイントは「ソート」ですね。
ソートにはいろんな種類がありますが、NHK教育番組の「しめじソート」をイメージすればいいと思います。
・まず、A,B,C,D,,,,,と並んでいるものをAとBを比較し、Aが小さければAとBの位置を交換。
・B,A,C,D,,,,となる。
・この状態で2番目と3番目であるAとCを比較し、小さいほうを後ろに、、、
・これを繰り返す
これで、1週目で一番小さいものが一番後ろに回ります。
さらに、これ全体をN回(A,B,C,D,,,の数)繰り返すと、きれいに大きい順に並んでくれる、というロジックで並び替えます。
あとは交互に処理をすればOK。交互に処理するには、「〇を2で割った余り」で0と1で場合分けすれば出来上がります!
ABC085B – Kagami Mochi
鏡餅もソートの問題です。
前の問題が解けた方は、これもソートの練習だと思って解いてみましょう!
ABC085C – Otoshidama
さて、ここからが300点問題です。本当に難しいと思います。
このレベルの場合、お子さんが興味を示さないのに無理にさせると、プログラミングが嫌いになる可能性があるので、無理をさせてはいけないと思います。
ただし、親が苦労している姿を子供に見せると、子供は逆に興味を持って「お父さん(お母さん)が解けない問題だ!!解いたら褒めてもらえる!!」と思って興味を持ってくれる可能性があるので、親が「むずかしーーー!!」って叫んでいる姿を子供に見せるのは良いことだと思います。
この問題は、「ABC087B – Coins」のように、総当たりで回答を見つければいい!!と直感するかもしれません。
ただ、これを3重繰り返し構文で処理するのは、、、AtCoderの罠なんです。
Nの値が2000通りあるので、これを3重繰り返し構文で総当たりさせると、2000の3乗=8,000,000,000通り(80億通り)の計算をさせることとなり、処理時間の2秒間では終わらず、タイムオーバするようになっています。
問題設定がうまいな~~って思います(はい。私も罠にハマりました。)
この問題は、10000 円札x 枚、5000 円札y 枚、1000 円札z 枚としたら、z = N – (x+y) となるので、x,y,zの3重繰り返し構文にする必要はなく、xとyの2重繰り返し構文で解けるという所がミソになります。(2重繰り返し構文ならタイムオーバはしません)
ABC049C – 白昼夢
この問題もすごく難しいです。
この問題のポイントは、前から処理していくと「dream&eraser」と「dreamer」の区別がつかないので、ハマってしまう所にあります。
この問題を解くミソは、文字列の逆から解いていくという所にあります。
つまりdreameraserをd,r,e,a,m,,,,と1文字目から照合していくのではなく、r,e,s,a,r,e,m,,,,と最終文字から逆順に1文字ずつ照合していくのです。
このアイディアは中々思いつきませんが、AtCoderではこの逆順ロジックはそれなりに登場します。
実際の世界でもエクセルに行を追加していくロジックを装備させる際、最終行から処理させていった方がスマートなコードを書けることがありますので、「逆順」という逆転の発想は身に付けておいて損はしないロジックになります。
1文字ずつチェックさせる方法(スマートではないけど、可読性は良いと思う)
Scratchの解法例リンク
繰り返し構文を使ったスマートな構文(可読性は非常に悪いです)
Scratchの解法例リンク
ABC086C – Traveling
この問題は「x,y方向に自由に移動できる」という状況に目がくらんでしまうと、どう解いてよいか分からなくなってしまいます。
まずは最短ルートで移動させ、余った歩数は左右にうろうろさせる状況をイメージ出来れば、この問題は単純に偶数か奇数かを判別する問題だと気付くことができるでしょう。
ただ、Scratchではほとんど使うことのない「絶対値」というブロックを使うこととなるので、ここで戸惑うことがあるかもしれません。
また、xとy座標、および歩数tが不特定多数であるためリストで処理する必要があるのも難易度を上げていると思います。
この辺りを小中学生の段階で解くことが出来たら、プログラミングスキルは本当にトップレベルだと思います。
おわりに
この記事では「ScratchでAtCoderに挑戦」について記事にしました。
実際にScratchでAtCoderに挑戦させる場合、「最初の10問」を解くのが良いと思います。
しかし、間違いなく最初の10問は所見ではクリアできません。
親御さんの温かい指導が要りますが、親御さんも初見で全て解ける人はいないと思います。
この記事がScratchでAtCoderに挑戦させる場合の道しるべになると嬉しく思います。