課題の解答¶
(課題の提出期限後に掲載する)
第 10 回「図形描画関数」
#include <iostream>
#include <cmath>
void DrawRectangleOutline(int width, int height, char ch)
{
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
if ((x == 0) || (x == width - 1) || (y == 0) || (y == (height - 1)))
{
std::cout << ch;
}
else
{
std::cout << ' ';
}
}
std::cout << '\n';
}
}
void DrawCheckerboard(int width, int height, int cellSize, char ch1, char ch2)
{
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
if ((((x / cellSize) + (y / cellSize)) % 2) == 0)
{
std::cout << ch1;
}
else
{
std::cout << ch2;
}
}
std::cout << '\n';
}
}
void DrawCircle(int radius)
{
for (int y = 0; y < (radius * 2); ++y)
{
for (int x = 0; x < (radius * 2); ++x)
{
double px = (x + 0.5);
double py = (y + 0.5);
double distanceFromCenter = std::sqrt((px - radius) * (px - radius) + (py - radius) * (py - radius)); // std::hypot((px - radius), (py - radius)) も可
if (distanceFromCenter <= (radius - 0.25)) // ここの微調整の数字は任意
{
std::cout << '#';
}
else if (distanceFromCenter <= (radius + 0.25)) // ここの微調整の数字は任意
{
std::cout << '+';
}
else
{
std::cout << ' ';
}
}
std::cout << '\n';
}
}
int main()
{
DrawRectangleOutline(10, 5, '*');
std::cout << '\n';
DrawRectangleOutline(3, 3, '#');
std::cout << '\n';
DrawRectangleOutline(1, 5, '@');
std::cout << '\n';
DrawCheckerboard(10, 8, 2, 'O', '#');
std::cout << '\n';
DrawCheckerboard(12, 10, 3, ' ', '#');
std::cout << '\n';
DrawCheckerboard(15, 15, 4, '-', '|');
std::cout << '\n';
DrawCircle(4);
std::cout << '\n';
DrawCircle(6);
std::cout << '\n';
DrawCircle(12);
std::cout << '\n';
}
第 9 回「ハッシュテーブルの利用」
#include <iostream>
#include <string>
#include <unordered_map>
int main()
{
// キー: C++ 用語
// 値: 第何回の講義で初登場したか
std::unordered_map<std::string, int> table;
table["#include"] = 1;
table["<iostream>"] = 1;
table["std::cin"] = 3;
table["double"] = 3;
table["if"] = 3;
table["&&"] = 3;
for (;;)
{
std::cout << "============================================================\n";
std::cout << "C++ 単語帳\n";
std::cout << "何をしますか。[1] 一覧表示 [2] 検索 [3] 登録 [4] 削除 [5] 終了\n> ";
int action;
std::cin >> action;
std::cin.ignore(1000, '\n');
if (action == 1)
{
std::cout << "() は初めて登場した講義回です。\n";
for (auto&& [key, value] : table)
{
std::cout << key << " (" << value << ")\n";
}
}
else if (action == 2)
{
std::cout << "検索する単語を入力してください。\n> ";
std::string keyword;
std::getline(std::cin, keyword);
if (table.find(keyword) == table.end())
{
std::cout << "見つかりませんでした。\n";
}
else
{
std::cout << "見つかりました。初登場は " << table[keyword] << " 回目の講義です。\n";
}
}
else if (action == 3)
{
std::cout << "登録する単語を入力してください。\n> ";
std::string keyword;
std::getline(std::cin, keyword);
if (table.find(keyword) == table.end())
{
std::cout << "初登場の講義回を入力してください。\n> ";
int lecture;
std::cin >> lecture;
std::cin.ignore(1000, '\n');
table[keyword] = lecture;
std::cout << "登録しました。\n";
}
else
{
std::cout << "既に登録されています。\n";
}
}
else if (action == 4)
{
std::cout << "削除する単語を入力してください。\n> ";
std::string keyword;
std::getline(std::cin, keyword);
if (table.find(keyword) == table.end())
{
std::cout << "見つかりませんでした。\n";
}
else
{
table.erase(keyword);
std::cout << "削除しました。\n";
}
}
else if (action == 5)
{
break;
}
}
}
第 8 回「年齢の統計」
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
// 年齢(採点時は別のパターンに書き換えられます)
std::vector<int> ages = { 20, 17, 22, 20, 18, 20, 19, 18, 20, 21 };
// 年齢を若い順にソートする
std::sort(ages.begin(), ages.end());
// 最年少の人の年齢
std::cout << "最年少: " << ages.front() << "\n";
// 最年長の人の年齢
std::cout << "最年長: " << ages.back() << "\n";
if (ages.size() % 2 == 1) // 奇数の場合
{
// 年齢の中央値
std::cout << "中央値: " << ages[ages.size() / 2] << "\n";
}
else // 偶数の場合
{
// 年齢の中央値は 2 つの値の平均
std::cout << "中央値: " << (ages[ages.size() / 2 - 1] + ages[ages.size() / 2]) / 2.0 << "\n";
}
// 年齢の合計
double sum = 0.0;
for (const auto& age : ages)
{
sum += age;
}
// 平均年齢(小数以下も含めた値)
std::cout << "平均年齢: " << (sum / ages.size()) << "\n";
// 未成年(18 歳未満)の人数
int minors = 0;
for (const auto& age : ages)
{
if (age < 18)
{
++minors;
}
else
{
break; // ソートされているので、18 歳以上の人が出てきたら、それ以降は 18 歳未満の人はいない
}
}
// 未成年(18 歳未満)の人数
std::cout << "未成年の人数: " << minors << "\n";
// 成人(18 歳以上)の人数
std::cout << "成人の人数: " << (ages.size() - minors) << "\n";
// 最も多い年齢の人数
int maxCount = 0;
// 現在調べてる年齢の人数
int count = 0;
// 現在調べてる年齢
int currentAge = -1;
for (const auto& age : ages)
{
if (age != currentAge)
{
currentAge = age;
count = 1;
}
else
{
++count;
}
if (maxCount < count)
{
maxCount = count;
}
}
// 最も多い年齢の人数
std::cout << "最も多い年齢の人数: " << maxCount << "\n";
}
第 7 回「文字の種類」
#include <iostream>
#include <string>
int main()
{
// 文字列の個数を受け取る
int n;
std::cin >> n;
for (int i = 0; i < n; ++i)
{
// 文字列を 1 個受け取る
std::string s;
std::cin >> s;
// 大文字のアルファベットの個数
int upperCount = 0;
// 小文字のアルファベットの個数
int lowerCount = 0;
// 数字の個数
int numberCount = 0;
// それ以外の文字の個数
int otherCount = 0;
for (size_t k = 0; k < s.size(); ++k)
{
char ch = s[k];
if ('A' <= ch && ch <= 'Z') // 大文字
{
++upperCount;
}
else if ('a' <= ch && ch <= 'z') // 小文字
{
++lowerCount;
}
else if ('0' <= ch && ch <= '9') // 数字
{
++numberCount;
}
else // それ以外
{
++otherCount;
}
}
std::cout << upperCount << ' ' << lowerCount << ' ' << numberCount << ' ' << otherCount << '\n';
}
}
第 6 回「カウントダウンタイマー」
Step 1¶
入力された時間だけカウントダウンするプログラムを作ります。
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
int minutes, seconds;
std::cin >> minutes >> seconds;
// カウントダウン時間(秒)
int time = (minutes * 60 + seconds);
for (int i = time; 0 <= i; --i)
{
std::cout << i << "\n";
}
}
Step 2¶
時間を分と秒に分けて表示します。
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
int minutes, seconds;
std::cin >> minutes >> seconds;
// カウントダウン時間(秒)
int time = (minutes * 60 + seconds);
for (int i = time; 0 <= i; --i)
{
// 分
int m = (i / 60);
// 秒
int s = (i % 60);
std::cout << m << ":" << s << "\n";
}
}
Step 3¶
秒が 1 桁の場合は 0 を付けて表示します。
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
int minutes, seconds;
std::cin >> minutes >> seconds;
// カウントダウン時間(秒)
int time = (minutes * 60 + seconds);
for (int i = time; 0 <= i; --i)
{
// 分
int m = (i / 60);
// 秒
int s = (i % 60);
if (s < 10) // 秒が 1 桁の場合は
{
// 0 を付けて 2 桁にする
std::cout << m << ":0" << s << "\n";
}
else
{
std::cout << m << ":" << s << "\n";
}
}
}
Step 4¶
進捗をパーセントで表示します。
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
int minutes, seconds;
std::cin >> minutes >> seconds;
// カウントダウン時間(秒)
int time = (minutes * 60 + seconds);
for (int i = time; 0 <= i; --i)
{
// 分
int m = (i / 60);
// 秒
int s = (i % 60);
if (s < 10) // 秒が 1 桁の場合は
{
// 0 を付けて 2 桁にする
std::cout << m << ":0" << s << " ";
}
else
{
std::cout << m << ":" << s << " ";
}
// 進捗(%)
int progress = ((time - i) * 100 / time);
// 進捗を出力する
std::cout << " [" << progress << " %]\n";
}
}
Step 5¶
プログレスバーを表示します。この例では幅を 10 としています。
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
int minutes, seconds;
std::cin >> minutes >> seconds;
// カウントダウン時間(秒)
int time = (minutes * 60 + seconds);
for (int i = time; 0 <= i; --i)
{
// 分
int m = (i / 60);
// 秒
int s = (i % 60);
if (s < 10) // 秒が 1 桁の場合は
{
// 0 を付けて 2 桁にする
std::cout << m << ":0" << s << " ";
}
else
{
std::cout << m << ":" << s << " ";
}
// 進捗(%)
int progress = ((time - i) * 100 / time);
// プログレスバーの黒部分の長さ
int b = (progress / 10);
// プログレスバーの白部分の長さ
int w = (10 - b);
// プログレスバーの黒部分を出力する
for (int x = 0; x < b; ++x)
{
std::cout << "#";
}
// プログレスバーの白部分を出力する
for (int x = 0; x < w; ++x)
{
std::cout << "_";
}
// 進捗を出力する
std::cout << " [" << progress << " %]\n";
}
}
Step 6¶
カウントダウンごとにスリープを入れます。
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
int minutes, seconds;
std::cin >> minutes >> seconds;
// カウントダウン時間(秒)
int time = (minutes * 60 + seconds);
for (int i = time; 0 <= i; --i)
{
// 分
int m = (i / 60);
// 秒
int s = (i % 60);
if (s < 10) // 秒が 1 桁の場合は
{
// 0 を付けて 2 桁にする
std::cout << m << ":0" << s << " ";
}
else
{
std::cout << m << ":" << s << " ";
}
// 進捗(%)
int progress = ((time - i) * 100 / time);
// プログレスバーの黒部分の長さ
int b = (progress / 10);
// プログレスバーの白部分の長さ
int w = (10 - b);
// プログレスバーの黒部分を出力する
for (int x = 0; x < b; ++x)
{
std::cout << "#";
}
// プログレスバーの白部分を出力する
for (int x = 0; x < w; ++x)
{
std::cout << "_";
}
// 進捗を出力する
std::cout << " [" << progress << " %]\n";
// 1 秒待機する
std::this_thread::sleep_for(std::chrono::milliseconds{ 1000 });
}
}
第 5 回「プログラムの改善」
① B さん¶
【問題点】
answer = 1
は比較演算子の ==
を使うべきところが代入演算子の =
になっているため、「1」以外を入力しても「正解!」と表示されてしまう。
【修正方法】
=
を ==
に変更する。
【機能追加】
正解以外を入力した際に、解説を表示する。
【コード】
#include <iostream>
int main()
{
std::cout << "アメリカの首都は?\n";
std::cout << "1: ワシントン D.C.\n2: パリ\n3: ニューヨーク\n4: ロンドン\n";
int answer;
std::cin >> answer;
if (answer == 1)
{
std::cout << "正解!\n";
}
else if (answer == 2)
{
std::cout << "残念!パリはフランスの首都です。\n";
}
else if (answer == 3)
{
std::cout << "残念!ニューヨークはアメリカの都市ですが、首都ではありません。\n";
}
else if (answer == 4)
{
std::cout << "残念!ロンドンはイギリスの首都です。\n";
}
else
{
std::cout << "1 から 4 の数字を入力してください。\n";
}
}
② C さん¶
【問題点】
90 <= score <= 100
のように、文法的に正しくない複数の比較演算子の連結をしているため、「30」などの入力でも「A」と判定されてしまう。
【修正方法】
90 <= score && score <= 100
のように、&&
でつなげる。または下記コードのように範囲の書き方を変更する。
【機能追加】
101 などの範囲外の値を入力した際に、エラーメッセージを表示する。
【コード】
#include <iostream>
int main()
{
std::cout << "点数を入力してください:\n";
int score;
std::cin >> score;
if (100 < score)
{
std::cout << "100 より大きい点数は入力できません。\n";
}
else if (90 <= score)
{
std::cout << "A\n";
}
else if (80 <= score)
{
std::cout << "B\n";
}
else if (70 <= score)
{
std::cout << "C\n";
}
else if (60 <= score)
{
std::cout << "D\n";
}
else if (0 <= score)
{
std::cout << "F\n";
}
else
{
std::cout << "0 より小さい点数は入力できません。\n";
}
③ D さん¶
【問題点】
int minute = (time / 60);
で、すでに「時」に変換された分も「分」に変換してしまっているため、例えば 4200 という入力に対して「1時間70分0秒」と表示されてしまう。
【修正方法】
int minute = (time % 3600) / 60;
のように、「時」の影響を除いて分を計算する。
【機能追加】
先頭の単位が 0 の場合、表示しないようにする。
【コード】
#include <iostream>
int main()
{
std::cout << "時間を秒で入力してください:\n";
int time;
std::cin >> time;
int hour = (time / 3600);
int minute = (time % 3600) / 60;
int second = (time % 60);
if (hour == 0)
{
if (minute == 0)
{
std::cout << second << "秒\n";
}
else
{
std::cout << minute << "分" << second << "秒\n";
}
}
else
{
std::cout << hour << "時間" << minute << "分" << second << "秒\n";
}
}
④ E さん¶
【問題点】
- 年の判定に問題はないが、月・日の判定を
&&
でつなげていることで条件が不必要に厳しくなってしまっている。例えば「1910 10 10」の入力に対して「大正」と表示されてしまう。 - 「大正以前」という表現は「大正」を含むので適切でない。
【修正方法】
if ((year < 1912) && (month < 7) && (day < 30))
は、if (year < 1912 || (year == 1912 && (month < 7 || (month == 7 && day < 30))))
に変更する。他の条件も同様に修正する。- 「大正以前」は「明治以前」のような表現に修正する。
【機能追加】
「令和 5 年」のように、その元号の何年目であるかも表示する。
【コード】
#include <iostream>
int main()
{
std::cout << "年月日を入力してください:\n";
int year, month, day;
std::cin >> year >> month >> day;
if (year < 1912 || (year == 1912 && (month < 7 || (month == 7 && day < 30))))
{
std::cout << "明治以前\n";
}
else if (year < 1926 || (year == 1926 && (month < 12 || (month == 12 && day < 25))))
{
std::cout << "大正 " << (year - 1911) << " 年\n";
}
else if (year < 1989 || (year == 1989 && (month == 1 && day < 8)))
{
std::cout << "昭和 " << (year - 1925) << " 年\n";
}
else if (year < 2019 || (year == 2019 && month < 5))
{
std::cout << "平成 " << (year - 1988) << " 年\n";
}
else
{
std::cout << "令和 " << (year - 2018) << " 年\n";
}
}
⑤ F さん¶
【問題点】
- ターンの先頭で毎回
playerHP
とenemyHP
という変数を作成しているため、前のターンの結果がリセットされてしまう。 - 主人公の攻撃で敵を倒したあとに、敵の攻撃が行われてしまうという不自然な挙動がある。
【修正方法】
- 変数
playerHP
とenemyHP
をループの前で作成する。 - 主人公の攻撃の直後に、敵の HP が 0 以下になったかどうかを判定する。
【機能追加】
- 回復アイテムの使用回数に上限を設ける。
- 逃げられる確率を 50% に設定し、逃げられないケースも用意する。
【コード】
#include <iostream>
#include <random> // 乱数用
// min 以上、max 以下の乱数を生成する関数
int Random(int min, int max)
{
std::random_device rng;
return std::uniform_int_distribution<int>{ min, max }(rng);
}
int main()
{
// 主人公の HP
int playerHP = 200;
// 敵の HP
int enemyHP = 200;
// 回復アイテムの所持数
int recoveryItemCount = 3;
for (;;)
{
std::cout << "----------------------------\n";
std::cout << "主人公\t HP: " << playerHP << "\n";
std::cout << "敵\t HP: " << enemyHP << "\n";
std::cout << "回復アイテム\t 所持数: " << recoveryItemCount << "\n";
std::cout << "----------------------------\n";
std::cout << "行動を選択してください\n";
std::cout << "1: 攻撃 2: 回復 3: 逃げる\n";
int action;
std::cin >> action;
std::cout << "----------------------------\n";
if (action == 1) // 攻撃
{
std::cout << "主人公の攻撃!\n";
// 敵に与えるダメージを 20 ~ 40 の範囲でランダムに決定
int damage = Random(20, 40);
std::cout << "敵に" << damage << "のダメージ!\n";
enemyHP -= damage;
}
else if (action == 2) // 回復
{
if (0 < recoveryItemCount)
{
playerHP += 100;
--recoveryItemCount;
std::cout << "主人公は 100 回復した!\n";
}
else
{
std::cout << "回復アイテムはもう無い!\n";
}
}
else if (action == 3) // 逃げる
{
int n = Random(0, 1);
if (n == 0)
{
std::cout << "逃げられなかった\n";
}
else
{
std::cout << "うまく逃げ切れた!\n";
break;
}
}
if (enemyHP <= 0)
{
std::cout << "敵を倒した!【勝利】\n";
break;
}
{
std::cout << "敵の攻撃!\n";
// 主人公に与えるダメージを 30 ~ 50 の範囲でランダムに決定
int damage = Random(30, 50);
std::cout << "主人公に" << damage << "のダメージ!\n";
playerHP -= damage;
}
if (playerHP <= 0)
{
std::cout << "主人公は力尽きた...【敗北】\n";
break;
}
}
}
第 4 回「宝くじ」
#include <iostream>
int main()
{
// 1 等の組と番号
int firstUnit, firstNumber;
std::cin >> firstUnit >> firstNumber;
// 2 等の番号
int secondNumber;
std::cin >> secondNumber;
// 3 等の番号(下 4 桁)
int thirdNumberN4;
std::cin >> thirdNumberN4;
// 4 等の番号(下 2 桁)
int fourthNumberN2;
std::cin >> fourthNumberN2;
// 5 等の番号(下 1 桁)
int fifthNumberN1;
std::cin >> fifthNumberN1;
// 1 等の前後賞の番号(前)
int firstNumberBefore = (firstNumber - 1);
// 例外的なルール
if (firstNumber == 100000)
{
firstNumberBefore = 199999;
}
// 1 等の前後賞の番号(後)
int firstNumberAfter = (firstNumber + 1);
// 例外的なルール
if (firstNumber == 199999)
{
firstNumberAfter = 100000;
}
int sum = 0;
for (;;)
{
// 購入者のくじの組と番号を入力する
int unit, number;
std::cin >> unit >> number;
// 終了
if ((unit == -1) && (number == -1))
{
break;
}
// 1 等、5 億円
if ((unit == firstUnit) && (number == firstNumber))
{
sum += 500000000;
}
// 1 等の前後賞(前)、1 億円
if ((unit == firstUnit) && (number == firstNumberBefore))
{
sum += 100000000;
}
// 1 等の前後賞(後)、1 億円
if ((unit == firstUnit) && (number == firstNumberAfter))
{
sum += 100000000;
}
// 1 等の組違い賞、10 万円
if ((unit != firstUnit) && (number == firstNumber))
{
sum += 100000;
}
// 2 等、100 万円
if (number == secondNumber)
{
sum += 1000000;
}
// 3 等、1 万円
if ((number % 10000) == thirdNumberN4)
{
sum += 10000;
}
// 4 等、3000 円
if ((number % 100) == fourthNumberN2)
{
sum += 3000;
}
// 5 等、300 円
if ((number % 10) == fifthNumberN1)
{
sum += 300;
}
}
// 合計当せん金額を出力する
std::cout << sum << "\n";
}
第 3 回「両替店」
#include <iostream>
int main()
{
// 標準入力から 8 つの為替レートを受け取る
double eur, jpy, gbp, aud, cad, cny, inr, chf;
std::cin >> eur >> jpy >> gbp >> aud >> cad >> cny >> inr >> chf;
// 標準入力から手数料率(%)を受け取る
double feeRate;
std::cin >> feeRate;
// 各通貨の為替レート(JPY)を計算する
double usd_jpy = (1.0 / jpy);
double eur_jpy = (usd_jpy * eur); // (eur / jpy) でも同じ
double gbp_jpy = (usd_jpy * gbp);
double aud_jpy = (usd_jpy * aud);
double cad_jpy = (usd_jpy * cad);
double cny_jpy = (usd_jpy * cny);
double inr_jpy = (usd_jpy * inr);
double chf_jpy = (usd_jpy * chf);
// 手数料を適用した倍率を計算する
double sellRate = (1.0 + feeRate / 100);
double buyRate = (1.0 - feeRate / 100);
std::cout << "USD: " << (usd_jpy * sellRate) << "\t" << (usd_jpy * buyRate) << "\n";
std::cout << "EUR: " << (eur_jpy * sellRate) << "\t" << (eur_jpy * buyRate) << "\n";
std::cout << "GBP: " << (gbp_jpy * sellRate) << "\t" << (gbp_jpy * buyRate) << "\n";
std::cout << "AUD: " << (aud_jpy * sellRate) << "\t" << (aud_jpy * buyRate) << "\n";
std::cout << "CAD: " << (cad_jpy * sellRate) << "\t" << (cad_jpy * buyRate) << "\n";
std::cout << "CNY: " << (cny_jpy * sellRate) << "\t" << (cny_jpy * buyRate) << "\n";
std::cout << "INR: " << (inr_jpy * sellRate) << "\t" << (inr_jpy * buyRate) << "\n";
std::cout << "CHF: " << (chf_jpy * sellRate) << "\t" << (chf_jpy * buyRate) << "\n";
}
第 2 回「数式を作る」
#include <iostream>
int main()
{
std::cout << (3 / 2 - 5 + 4) << "\n"; // 0
std::cout << ((5 - 4) * (3 - 2)) << "\n"; // 1
std::cout << ((5 + 3 - 4) - 2) << "\n"; // 2
std::cout << (5 + 4 - 3 * 2) << "\n"; // 3
std::cout << ((5 * 4) / (3 + 2)) << "\n"; // 4
std::cout << ((5 * 3) % 4 + 2) << "\n"; // 5
std::cout << (5 + 3 + 2 - 4) << "\n"; // 6
std::cout << (5 * 3 - 4 * 2) << "\n"; // 7
std::cout << (5 + 4 - (3 - 2)) << "\n"; // 8
std::cout << ((5 + 4) * (3 - 2)) << "\n"; // 9
std::cout << (5 + 4 + 3 - 2) << "\n"; // 10
std::cout << (5 * 2 + 4 - 3) << "\n"; // 11
std::cout << ((5 + 3) * 2 - 4) << "\n"; // 12
std::cout << (5 * 3 - (4 - 2)) << "\n"; // 13
std::cout << (5 + 4 + 3 + 2) << "\n"; // 14
std::cout << (5 * (4 - 3 + 2)) << "\n"; // 15
std::cout << ((5 + 3) * (4 - 2)) << "\n"; // 16
std::cout << (5 * 3 + 4 - 2) << "\n"; // 17
std::cout << 4 * 5 - 2 % 3 << "\n"; // 18
std::cout << (5 * 4 - (3 - 2)) << "\n"; // 19
std::cout << 5 * 4 + 2 / 3 << "\n"; // 20
}
第 1 回「プログラミングのアドバイス」
① B さん¶
改行文字 \n が、文章(文字列)を表す " " の中に入っていません。
\n は特殊な記号なので、文章の要素のようには見えないかも知れません。
でも実際は、改行文字はその名前の通り「S」や「o」と同じように、文字の一種です。
そのことを意識すると、今後は間違えないと思います。
② C さん¶
③ D さん¶
コードの先頭に書くべき #include <iostream> が main の内部に書かれています。
また、出力の記号 << の < と < の間に空白をいれてはいけません。
プログラムは、ただ必要なことを書くだけでなく、どこに何を書くかも重要になります。
お手本と比べるときは、順番や空白も含めて注意して見てみましょう。