0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

コピペで学ぶAtCoder/C++入門、別解地獄【環境設定不要】

Last updated at Posted at 2023-11-26

前置き

この記事は、「本当に何も分からないけど、AtCoderをやりたい人」に向けた記事です。
環境設定は不要です。

記事の特徴

・○○の知識があれば、△△の問題が解ける。
この記事の特徴ではありません。

・△△の問題から、○○の知識が得られる。
この記事の特徴です。

知ることができるもの

  • AtCoder公式が提供しているC++入門ページの存在

  • コードテストページの存在とサンプル確認方法

  • デバッグ出力の存在と使い方

記事の概要

AtCoder公式のC++入門ページを参考にして、ほぼコピペでABC(AtCoder Beginner Contest)の基礎となる、以下の代表的なカテゴリ3問を解く手順を説明します。
また、正解するだけでなく、応用力を身に付けるための手掛かりも残しています。

問題カテゴリ 問題 問題ページ 参考にするページ 参考にする章 参考にする項
四則演算 ABC326A https://atcoder.jp/contests/abc326/tasks/abc326_a https://atcoder.jp/contests/APG4b/tasks/APG4b_g 「前の条件が真でないとき」の処理 else if
数列 ABC324A https://atcoder.jp/contests/abc324/tasks/abc324_a https://atcoder.jp/contests/APG4b/tasks/APG4b_l breakとcontinue break
文字列 ABC327A https://atcoder.jp/contests/abc327/tasks/abc327_a https://atcoder.jp/contests/APG4b/tasks/APG4b_m 応用 ループ構文との組み合わせ

記事の対象者

「AtCoderやりたいけど、プログラミング分からないし、何をしていいのか分からない。」と言っている人。
そんな人に、手ほどきする記事となれば幸いです。
また、「この記事を勉強の手掛かりにすると良いよ」と紹介されるようになったらいいな?と思っています。

記事のレベル感

この記事は、以下の素晴らしい記事の章「3.Hello World --- practice contest (A 問題のみ)」~「4.practice の次は???」の間くらいを説明しているつもりです。

@drken(けんちょん (Otsuki))様の記事の

プログラミングの知識がある人向けならば、以上の記事をおすすめします。

はじめる

設定

1.AtCoderに登録する。
@drken(けんちょん (Otsuki))様の記事の「2.AtCoder への登録」参照。

2.以下のページを開く。

2.コードテストページを開く。

事前準備2の画像

3.使用する言語を選択する。(C++で始まる言語を選択してください)

事前準備3の画像

4.エディタの設定をする。(しなくても良いです。デフォルトで使い辛いと思ったときにでも設定すれば良いかと)
※私は、画像のとおりに設定しています

事前準備4の画像

5.事前準備は完了です。

以後、問題ページとコードテストページと参考ページの計3ページを開いた状態で、この記事を読み進めることを想定しています。

本編

四則演算の問題を解く

問題のページ : ABC326のA

コードテストのページ : アカウント登録、ログイン後にアクセスしてください

参考にするページ :

参考にする章 : 「前の条件が真でないとき」の処理
参考にする項 : else if

回答手順

1.参考にするページの章『「前の条件が真でないとき」の処理』 - 項『else if』の下にあるコード欄の右上にあるcopyボタンを押す。

copyボタンとは?

2.「コードテスト」に貼り付ける。

3.参考にするページの章『論理演算子』の表の下にあるコード欄の5行目と6行目をコピーする。

コピー箇所

4.以下のとおりにコードを差し替え、コードのcinの行を、問題ページの入力内容に合わせる。

入力とは?

手順4適用箇所.cpp
  int x;
  cin >> x;

5.コードの数値を、問題文の数値に合わせる。

以下は、手順1から5までを実施した状態のコード例です。
手順1のコードから、どう変わったのか見比べてみてください。

手順1~5を適用したあとのコード一例.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;

  if (y-x < -3) {
    cout << "y-xは-3より小さい" << endl;
  }
  else if (y-x > 2) {
    cout << "y-xは-3より小さくなくて、2より大きい" << endl;
  }
  else if (y-x == 15) {
    cout << "y-xは-3より小さくなくて、2より大きくなくて、15である" << endl;
  }
  else {
    cout << "y-xは-3より小さくなくて、2より大きくもなくて、15でもない" << endl;
  }
}

6.参考ページには、「else ifの後に続けてelse ifやelseを書くこともできます。次のプログラムはその例です。」
と記載があり、そのとおりなので、不要な処理は削除する。

手順6を適用したあとのコード一例.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;

  if (y-x < -3) {
    cout << "y-xは-3より小さい" << endl;
  }
  else if (y-x > 2) {
    cout << "y-xは-3より小さくなくて、2より大きい" << endl;
  }
  else {
    cout << "y-xは-3より小さくなくて、2より大きくもなくて、15でもない" << endl;
  }
}

7.コードのcoutの行を、問題文が求めている出力に合わせる。

出力とは?

手順7を適用したあとのコード一例.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;

  if (y-x < -3) {
    cout << "No" << endl;
  }
  else if (y-x > 2) {
    cout << "No" << endl;
  }
  else {
    cout << "Yes" << endl;
  }
}

8.完成!!

図解

図解

サンプル確認~提出

サンプル確認方法

各問題には1個以上、入力例(いわゆるサンプル)があります。
慣れるまでは、提出する前にすべてのサンプルを試すようにしましょう。
サンプルを試さず提出して、それが不正解だったら悲しいです。

サンプル1の確認方法を説明する画像

サンプル2の確認方法を説明する画像

サンプル3の確認方法を説明する画像

提出方法

以下は、提出方法の一例です。

提出方法

正解すると、灰色のアイコンが緑色に変わり、ACと表示されます。

正解画面

補足

ここから先は、「四則演算の問題を解く」の補足です。
記述の幅を広げたい場合は、気になった箇所を見てみてください。
不要であれば、「数列の問題を解く」に進んでください。

コードの説明
1行目の解説箇所.cpp
#include <bits/stdc++.h>

細かい話 参照

2行目の解説箇所.cpp
using namespace std;

細かい話 参照

4行目の解説箇所.cpp
int main() {

main関数 参照

5行目の解説箇所.cpp
  int x,y;

全体参照

数値型 参照
他の数値型 参照

6行目の解説箇所.cpp
  cin >> x >> y;

入力 参照
繋げて入力 参照

8行目の解説箇所.cpp
  if (y-x < -3) {

9行目の解説箇所.cpp
    cout << "No" << endl;

cout 参照

10行目の解説箇所.cpp
  }

11行目の解説箇所.cpp
  else if (y-x > 2) {

14行目の解説箇所.cpp
  else {

17行目の解説箇所.cpp
}

全体参照

main関数 参照

別解

他のページを参考にすることで、提出したコードとは異なるコードでの正解も可能です。

別解1

論理演算子 表 上から3つ目の演算子 参照

別解1.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;

  if (y-x < -3 || y-x > 2) {
    cout << "No" << endl;
  }
  else {
    cout << "Yes" << endl;
  }
}

図解

図解

別解2

論理演算子 表 上から2つ目の演算子 参照

別解2.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;

  if (-3 <= y-x && y-x <= 2) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

別解3

論理演算子 表 上から1つ目の演算子 参照

別解3.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;

  if (!(-3 <= y-x && y-x <= 2)) {
    cout << "No" << endl;
  }
  else {
    cout << "Yes" << endl;
  }
}

図解

図解

別解4

細かい話 { } の省略 参照

別解4(別解2の別解その1).cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;

  if (-3 <= y-x && y-x <= 2)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}

図解

図解

別解5

参照先なし

別解5(別解4の別解).cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;

  if (-3 <= y-x && y-x <= 2)cout << "Yes" << endl;
  else                      cout << "No" << endl;
}

図解

図解

別解6

if文 xが10より小さく無い場合、次の処理は飛ばされます。行の次の欄 参照

別解6.cpp
#include <bits/stdc++.h>
using namespace std;

int main()
{
  int x,y;
  cin >> x >> y;

  if (y-x < -3)
  {
    cout << "No" << endl;
  }
  else if (y-x > 2)
  {
    cout << "No" << endl;
  }
  else
  {
    cout << "Yes" << endl;
  }
}

図解

図解

別解7

参照なし
数式のxとyを逆にする

別解7.cpp
#include <bits/stdc++.h>
using namespace std;

int main()
{
  int x,y;
  cin >> x >> y;

  if (y-x > 2)
  {
    cout << "No" << endl;
  }
  else if (y-x < -3)
  {
    cout << "No" << endl;
  }
  else
  {
    cout << "Yes" << endl;
  }
}

図解

図解

別解8

細かい話 if文のネスト 参照

別解8.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;

  if (-3 <= y-x) {
    if (y-x <= 2) {
      cout << "Yes" << endl;
    }
    else {
      cout << "No" << endl;
    }
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

別解9

複合代入演算子 +=以外の複合代入演算子 参照

別解9.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  y -= x;

  if (y < -3) {
    cout << "No" << endl;
  }
  else if (y > 2) {
    cout << "No" << endl;
  }
  else {
    cout << "Yes" << endl;
  }
}

図解

図解

別解10

複合代入演算子 +=以外の複合代入演算子 参照
別解9の数式のxとyを逆にする

別解10.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  x -= y;

  if (x > 3) {
    cout << "No" << endl;
  }
  else if (x < -2) {
    cout << "No" << endl;
  }
  else {
    cout << "Yes" << endl;
  }
}

図解

図解

別解11

参照なし

別解11.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  if (diff == 2) {
    cout << "Yes" << endl;
  }
  else if (diff == 1) {
    cout << "Yes" << endl;
  }
  else if (diff == 0) {
    cout << "Yes" << endl;
  }
  else if (diff == -1) {
    cout << "Yes" << endl;
  }
  else if (diff == -2) {
    cout << "Yes" << endl;
  }
  else if (diff == -3) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

別解12

参照なし
switch/case文

別解12(別解11の別解).cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  switch (diff) {
  case 2:
    cout << "Yes" << endl;
    break;
  case 1:
    cout << "Yes" << endl;
    break;
  case 0:
    cout << "Yes" << endl;
    break;
  case -1:
    cout << "Yes" << endl;
    break;
  case -2:
    cout << "Yes" << endl;
    break;
  case -3:
    cout << "Yes" << endl;
    break;
  default:
    cout << "No" << endl;
    break;
  }
}

図解

図解

別解13

参照なし
switch/case文

別解13(別解12の別解).cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  switch (diff) {
  case 2:
  case 1:
  case 0:
  case -1:
  case -2:
  case -3:
    cout << "Yes" << endl;
    break;
  default:
    cout << "No" << endl;
    break;
  }
}

図解

図解

別解14

全体参照

return文の動作 参照
返り値の指定忘れ 参照

別解14.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  for (int i = -3; i <= 2; i++) {
    if (diff == i) {
      cout << "Yes" << endl;
      return 0;
    }
  }
  cout << "No" << endl;
}

図解

図解

別解15

全体参照

インクリメントとデクリメント 参照

return文の動作 参照
返り値の指定忘れ 参照

別解15.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  for (int i = 2; -3 <= i; i--) {
    if (diff == i) {
      cout << "Yes" << endl;
      return 0;
    }
  }
  cout << "No" << endl;
}

図解

図解

別解17

全体参照

全体参照

インクリメントとデクリメント 参照

return文の動作 参照
返り値の指定忘れ 参照

別解17.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  int i;
  i = -3;
  while (i <= 2) {
    if (diff == i) {
      cout << "Yes" << endl;
      return 0;
    }
    i++;
  }
  cout << "No" << endl;
}

図解

図解

別解18

全体参照

全体参照

return文の動作 参照
返り値の指定忘れ 参照

別解18.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  int i;
  i = 2;
  while (-3 <= i) {
    if (diff == i) {
      cout << "Yes" << endl;
      return 0;
    }
    i--;
  }
  cout << "No" << endl;
}

図解

図解

別解19

全体参照

bool型 参照

別解19(別解14の別解).cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  bool yes = false;
  for (int i = -3; i <= 2; i++) {
    if (diff == i) {
      yes = true;
    }
  }
  
  if (yes) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

別解20

全体参照

bool型 参照

条件演算子 if文の書き換え 参照

演算子の優先順位 参照

別解20(別解19の別解).cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  bool yes = false;
  for (int i = -3; i <= 2; i++) {
    if (diff == i) {
      yes = true;
    }
  }
  
  cout << (yes ? "Yes" : "No") << endl;
}

図解

図解

別解21

全体参照

応用 ループ構文との組み合わせ 参照

インクリメントとデクリメント 参照

別解21(別解14の別解).cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  int count = 0;
  for (int i = -3; i <= 2; i++) {
    if (diff == i) {
      count++;
    }
  }
  
  if (0 < count) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

別解21

全体参照

応用 ループ構文との組み合わせ 参照

インクリメントとデクリメント 参照

演算子の優先順位 参照

別解22(別解21の別解).cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  int count = 0;
  for (int i = -3; i <= 2; i++) {
    if (diff == i) {
      count++;
    }
  }

  cout << (0 < count ? "Yes" : "No") << endl;
}

図解

図解

別解23

インクリメントとデクリメント 参照

別解23.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;

  int count = 0;
  if (-3 <= y-x) {
    count++;
  }
  if (y-x <= 2) {
    count++;
  }

  if (count == 2) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

別解24

条件演算子 if文の書き換え 参照

インクリメントとデクリメント 参照

演算子の優先順位 参照

別解24(別解23の別解).cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;

  int count = 0;
  if (-3 <= y-x) {
    count++;
  }
  if (y-x <= 2) {
    count++;
  }

  cout << (count == 2 ? "Yes" : "No") << endl;
}

図解

図解

別解25

全体参照

return文の動作 参照
返り値の指定忘れ 参照

別解25.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x,y;
  cin >> x >> y;
  int diff;
  diff = y - x;

  int ansList[6] = {-3, -2, -1, 0, 1, 2};
  for (int i = 0; i < 6; i++) {
    if (diff == ansList[i]) {
      cout << "Yes" << endl;
      return 0;
    }
  }
  cout << "No" << endl;
}

図解

図解

別解補足

その他にもまだまだ数えきれないほど別解は存在します。
他の問題を解くことで、記述の幅を広げることができます。


数列の問題を解く

問題のページ : ABC324のA

コードテストのページ : アカウント登録、ログイン後にアクセスしてください

参考にするページ :

参考にする章 : breakとcontinue
参考にする項 : break

手順

1.以下のページの章『プログラムの基本形』の『この形式は今後解説するプログラムのほぼ全てに登場しますが、暗記する必要はありません。』の下にあるコード欄の右上にあるcopyボタンを押す。

2.「コードテスト」に貼り付ける。

3.コードのcinの行を、問題ページの入力内容に合わせる。

入力とは?

3-1.以下のページの章『配列の使い所』 - 項『解答例』の『配列とfor文を使えば、Nの大きさに関わらず簡潔に処理を書くことができます。』の下にあるコード欄の5, 6行目をコピーする。

コピー該当行.cpp
  int N;
  cin >> N;

3-2.「コードテスト」の以下の行の間に貼り付ける。

追加場所.cpp
int main() {
}

3-3.以下のページの章『キーポイント』の『配列でN個の入力を受け取るときは、N要素で初期化した後、for文の中でatを使って1ずつ受け取る』の下にあるコード欄の右上にあるcopyボタンを押す。

3-4.「コードテスト」の以下の行の間に貼り付ける。

追加場所.cpp
  cin >> N;
}

4.以下のページの章『比較演算子』の『次のプログラムは、入力された整数値がどんな条件を満たしているかを出力するプログラムです。』の下にあるコード欄の20~22行目をコピーする。

コピー該当行.cpp
  if (x != 100) {
    cout << "xは100ではない" << endl;
  }

5.「コードテスト」の以下の行と差し替える。

差し替え箇所.cpp
    cin >> vec.at(i);

6.以下のページの章『2章の内容の紹介』 - 項『再帰関数』の『このような関数を再帰関数と言います。これについては2.05.再帰で詳しく説明します。 』の下にあるコード欄の7行目をコピーする。

コピー該当行.cpp
      return 0;

7.以下のページの章『出力』の『先程述べた通り、main関数の中だけに注目しましょう。このプログラムのmain関数の中には次の1行のプログラムが書かれています。』の下にあるコード欄の右上にあるcopyボタンを押す。

8.「コードテスト」の以下の行の間に貼り付ける。

追加場所.cpp
  }
}

9.以下のコードの内容を、問題文の内容に合わせる。

修正前.cpp
    if (x != 100) {
修正後.cpp
    if (vec.at(i) != vec.at(0)) {

10.コードのcoutの行を、問題文が求めている出力に合わせる。

出力とは?

以下は、手順1から10までを実施した状態のコード例です。

手順1~10を適用したあとのコード一例.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec.at(i);
  }

  for (int i = 0; i < N; i++) {
    if (vec.at(i) != vec.at(0)) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}

図解

図解

11.完成!!

サンプル確認~提出

サンプル確認方法

各問題には1個以上、入力例(いわゆるサンプル)があります。
慣れるまでは、提出する前にすべてのサンプルを試すようにしましょう。
サンプルを試さず提出して、それが不正解だったら悲しいです。

サンプル1の確認方法を説明する画像

サンプル2の確認方法を説明する画像

サンプル3の確認方法を説明する画像

提出

正解すると、灰色のアイコンが緑色に変わり、ACと表示されます。

正解画面

補足

ここから先は、「数列の問題を解く」の補足です。
記述の幅を広げたい場合は、気になった箇所を見てみてください。
不要であれば、「文字列の問題を解く」に進んでください。

コードの説明
1行目の解説箇所.cpp
#include <bits/stdc++.h>

細かい話 参照

2行目の解説箇所.cpp
using namespace std;

細かい話 参照

4行目の解説箇所.cpp
int main() {

5行目の解説箇所.cpp
  int N;

全体参照

数値型 参照
他の数値型 参照

6行目の解説箇所.cpp
  cin >> N;

入力 参照

8行目の解説箇所.cpp
  vector<int> vec(N);

配列と文字列 配列変数の宣言 参照

9行目の解説箇所.cpp
  for (int i = 0; i < N; i++) {

for文 N回の繰り返し処理 参照

10行目の解説箇所.cpp
    cin >> vec.at(i);

入力 参照
繋げて入力 参照

配列と文字列 i番目の要素 参照

11行目の解説箇所.cpp
  }

14行目の解説箇所.cpp
    if (vec.at(i) != vec.at(0)) {

配列と文字列 i番目の要素 参照

15行目の解説箇所.cpp
      cout << "No" << endl;

cout 参照

16行目の解説箇所.cpp
      return 0;

return文の動作 参照
返り値の指定忘れ 参照

20行目の解説箇所.cpp
}

全体参照

main関数 参照

別解

他のページを参考にすることで、提出したコードとは異なるコードでの正解も可能です。

別解1

細かい話 atを使わないi番目の要素へのアクセス 参照

別解1.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec[i];
  }

  for (int i = 0; i < N; i++) {
    if (vec[i] != vec[0]) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}

図解

図解

別解2

細かい話 vector以外の配列 参照

別解2.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  int data[N];
  for (int i = 0; i < N; i++) {
    cin >> data[i];
  }

  for (int i = 0; i < N; i++) {
    if (data[i] != data[0]) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}

図解

図解

別解3

細かい話 vector以外の配列 参照

別解3.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  array<int , 100> data;
  for (int i = 0; i < N; i++) {
    cin >> data.at(i);
  }

  for (int i = 0; i < N; i++) {
    if (data.at(i) != data.at(0)) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}

図解

図解

別解4

細かい話 vector以外の配列 参照
細かい話 atを使わないi番目の要素へのアクセス 参照

別解4.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  array<int , 100> data;
  for (int i = 0; i < N; i++) {
    cin >> data[i];
  }

  for (int i = 0; i < N; i++) {
    if (data[i] != data[0]) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}

図解

図解

別解5

参照なし

別解5.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec.at(i);
    
    if (vec.at(i) != vec.at(0)) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}

図解

図解

別解6

参照なし

別解6.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec.at(i);
  }

  for (int i = 0; i < N-1; i++) {
    if (vec.at(i) != vec.at(i+1)) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}

図解

図解

別解7

参照なし

別解7.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec.at(i);
  }

  for (int i = 1; i < N; i++) {
    if (vec.at(i-1) != vec.at(i)) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}

図解

図解

別解8

STLの関数 関数の使い方 参照
関数の例 min関数 参照
関数の例 max関数 参照

別解8.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec[i];
  }

  int minAnswer = vec.at(0);
  int maxAnswer = vec.at(0);

  for (int i = 1; i < N; i++) {
    minAnswer = min(minAnswer, vec.at(i));
    maxAnswer = max(maxAnswer, vec.at(i));
  }

  if (minAnswer == maxAnswer) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

別解9, 10

STLの関数 関数の使い方 参照
関数の例 min関数 参照
関数の例 max関数 参照

別解9, 10.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  int minAnswer = 100;
  int maxAnswer = 0;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec.at(i);

    minAnswer = min(minAnswer, vec.at(i));
    maxAnswer = max(maxAnswer, vec.at(i));
  }

  if (minAnswer == maxAnswer) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

以下の記載でも、正解可能です。
条件演算子 if文の書き換え 参照

修正箇所.cpp
  if (minAnswer == maxAnswer) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }

修正後.cpp
  cout << (minAnswer == maxAnswer ? "Yes" : "No" << endl;
別解11, 12

参考なし

別解11, 12.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec.at(i);
  }
  int minAnswer = *min_element(vec.begin(), vec.end());
  int maxAnswer = *max_element(vec.begin(), vec.end());

  if (minAnswer == maxAnswer) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

以下の記載でも、正解可能です。
条件演算子 if文の書き換え 参照

修正箇所.cpp
  if (minAnswer == maxAnswer) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }

修正後.cpp
  cout << (minAnswer == maxAnswer ? "Yes" : "No" << endl;
別解13, 14

参考なし

別解13, 14.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec.at(i);
  }

  auto answer = minmax_element(vec.begin(), vec.end());
  if (*answer.first == *answer.second) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

以下の記載でも、正解可能です。
条件演算子 if文の書き換え 参照

修正箇所.cpp
  if (*answer.first == *answer.second) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }

修正後.cpp
  cout << (*answer.first == *answer.second ? "Yes" : "No" << endl;
別解15, 16

配列を引数にする関数 sort関数 参照

別解15, 16.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec.at(i);
  }

  sort(vec.begin(), vec.end());

  if (vec.at(0) == vec.at(N-1)) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

以下の記載でも、正解可能です。
条件演算子 if文の書き換え 参照

修正箇所.cpp
  if (vec.at(0) == vec.at(N-1)) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }

修正後.cpp
  cout << (vec.at(0) == vec.at(N-1) ? "Yes" : "No" << endl;
別解17, 18

配列を引数にする関数 sort関数 参照

別解17, 18.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec.at(i);
  }

  sort(begin(vec), end(vec));

  if (vec.at(0) == vec.at(N-1)) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

以下の記載でも、正解可能です。
条件演算子 if文の書き換え 参照

修正箇所.cpp
  if (vec.at(0) == vec.at(N-1)) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }

修正後.cpp
  cout << (vec.at(0) == vec.at(N-1) ? "Yes" : "No" << endl;
別解19, 20

参照なし

別解19, 20.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  int all[100];
  for (int i = 0; i < N; i++) {
    int in;
    cin >> in;
    all[in - 1]++;
  }

  int typenumber = 0;
  for (int i = 0; i < N; i++) {
    if (0 < all[i]) {
      typenumber++;
    }
  }
  
  if (typenumber == 1) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

以下の記載でも、正解可能です。
条件演算子 if文の書き換え 参照

修正箇所.cpp
  if (typenumber == 1) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }

修正後.cpp
  cout << (typenumber == 1 ? "Yes" : "No" << endl;
別解21, 22

bool型 参照

別解21, 22.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  int all[100];
  for (int i = 0; i < N; i++) {
    int in;
    cin >> in;
    all[in - 1]++;
  }

  bool yes = false;
  for (int i = 0; i < N; i++) {
    if (all[i] == N) {
      yes = true;
    }
  }
  
  if (yes) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

以下の記載でも、正解可能です。
条件演算子 if文の書き換え 参照

修正箇所.cpp
  if (yes) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }

修正後.cpp
  cout << (yes ? "Yes" : "No" << endl;
別解23, 24

参照なし

別解23, 24.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  int all[100];
  int in;
  for (int i = 0; i < N; i++) {
    cin >> in;
    all[in - 1]++;
  }

  if (all[in - 1] == N) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

以下の記載でも、正解可能です。
条件演算子 if文の書き換え 参照

修正箇所.cpp
  if (all[in - 1] == N) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }

修正後.cpp
  cout << (all[in - 1] == N ? "Yes" : "No" << endl;
別解25, 26

細かい話 set 参照

別解25, 26.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  set<int> s;
  for (int i = 0; i < N; i++) {
    int in;
    cin >> in;
    s.insert(in);
  }

  if (s.size() == 1) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

以下の記載でも、正解可能です。
条件演算子 if文の書き換え 参照

修正箇所.cpp
  if (s.size() == 1) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }

修正後.cpp
  cout << (s.size() == 1 ? "Yes" : "No" << endl;
別解27, 28

bool型 参照

別解27, 28.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec.at(i);
  }

  bool ok = true;
  for (int i = 0; i < N; i++) {
    if (vec.at(i) != vec.at(0)) {
      ok = false;
      break;
    }
  }
  
  if (ok) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }
}

図解

図解

以下の記載でも、正解可能です。
条件演算子 if文の書き換え 参照

修正箇所.cpp
  if (ok) {
    cout << "Yes" << endl;
  }
  else {
    cout << "No" << endl;
  }

修正後.cpp
  cout << (ok ? "Yes" : "No" << endl;
別解29

その他の機能 要素の追加 参照

別解29.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec;
  for (int i = 0; i < N; i++) {
    int in;
    cin >> in;
    vec.push_back(in);
  }

  for (int i = 0; i < N; i++) {
    if (vec.at(i) != vec.at(0)) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}

図解

図解

別解30

その他の機能 要素の追加 参照
配列と文字列 配列の要素数 参照

別解30.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec;
  for (int i = 0; i < N; i++) {
    int in;
    cin >> in;
    vec.push_back(in);
  }

  for (int i = 0; i < vec.size(); i++) {
    if (vec.at(i) != vec.at(0)) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}

図解

図解

別解31

範囲for文 参照

別解31.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;

  vector<int> vec(N);
  for (int i = 0; i < N; i++) {
    cin >> vec.at(i);
  }

  for (auto v : vec) {
    if (v != vec.at(0)) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}

図解

図解

別解補足

その他にもまだまだ数えきれないほど別解は存在します。
他の問題を解くことで、記述の幅を広げることができます。


文字列の問題を解く

問題のページ : ABC327のA

コードテストのページ : アカウント登録、ログイン後にアクセスしてください

参考にするページ :

参考にする章 : 応用
参考にする項 : ループ構文との組み合わせ

手順

1.参考にする項の「次のプログラムでは、入力された文字に何文字'O'が含まれているかを数えています。 」の下にあるコード欄の右上にあるcopyボタンを押す。

2.「コードテスト」に貼り付ける。

3.以下のとおりにコードを差し替え、コードのcinの行を、問題ページの入力内容に合わせる。

入力とは?

3-1.以下のページの章『配列の使い所』 - 項『解答例』の『配列とfor文を使えば、Nの大きさに関わらず簡潔に処理を書くことができます。』の下にあるコード欄の5, 6行目をコピーする。

コピー該当行.cpp
  int N;
  cin >> N;

3-2.「コードテスト」の以下の行の間に貼り付ける。

追加場所.cpp
int main() {
  string str;

4.以下のコードの内容を、問題文の内容に合わせる。

修正前.cpp
    if (str.at(i) == 'O') {
      count++;
    }
修正後.cpp
    if (str.at(i) == 'a' && str.at(i+1) == 'b') {
      //"ab"を見つけた
      count++;
    }
    if (str.at(i) == 'b' && str.at(i+1) == 'a') {
      //"ba"を見つけた
      count++;
    }

5.コードのcoutの行を、問題文が求めている出力に合わせる。

出力とは?

修正前.cpp
  cout << count << endl;
修正後.cpp
  if (0 == count) {
    cout << "No" << endl;
  }
  else {
    cout << "Yes" << endl;
  }
手順1~5を適用したあとのコード一例.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;
  string str;
  cin >> str;

  int count = 0;
  for (int i = 0; i < str.size(); i++) {
    if (str.at(i) == 'a' && str.at(i+1) == 'b') {
      //"ab"を見つけた
      count++;
    }
    else if (str.at(i) == 'b' && str.at(i+1) == 'a') {
      //"ba"を見つけた
      count++;
    }
  }

  if (0 == count) {
    cout << "No" << endl;
  }
  else {
    cout << "Yes" << endl;
  }
}

6.エラー修正をする。

※手順5のコードでは、以下のページの章『注意事項』 - 項『範囲外エラー』と同じエラーが発生します。

エラーを除去するために、以下のコード箇所を修正する。

修正前のコード箇所.cpp
  for (int i = 0; i < str.size(); i++) {
修正後のコード.cpp
  for (int i = 0; i < str.size() - 1; i++) {
範囲外エラーを修正したコードの一例.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;
  string str;
  cin >> str;

  int count = 0;
  for (int i = 0; i < str.size() - 1; i++) {
    if (str.at(i) == 'a' && str.at(i+1) == 'b') {
      //"ab"を見つけた
      count++;
    }
    else if (str.at(i) == 'b' && str.at(i+1) == 'a') {
      //"ba"を見つけた
      count++;
    }
  }

  if (0 == count) {
    cout << "No" << endl;
  }
  else {
    cout << "Yes" << endl;
  }
}

7.完成!!

サンプル確認~提出

サンプル確認方法

各問題には1個以上、入力例(いわゆるサンプル)があります。
慣れるまでは、提出する前にすべてのサンプルを試すようにしましょう。
サンプルを試さず提出して、それが不正解だったら悲しいです。

サンプル1の確認方法を説明する画像

サンプル2の確認方法を説明する画像

サンプル3の確認方法を説明する画像

提出

正解すると、灰色のアイコンが緑色に変わり、ACと表示されます。

正解画面

補足

ここから先は、「文字列の問題を解く」の補足です。
記述の幅を広げたい場合は、気になった箇所を見てみてください。
不要であれば、「デバッグ出力をしたい」に進んでください。

コードの説明
1行目の解説箇所.cpp
#include <bits/stdc++.h>

細かい話 参照

2行目の解説箇所.cpp
using namespace std;

細かい話 参照

4行目の解説箇所.cpp
int main() {

5行目の解説箇所.cpp
  int n;

全体参照

数値型 参照
他の数値型 参照

6行目の解説箇所.cpp
  cin >> n;

入力 参照

7行目の解説箇所.cpp
  string str;

全体参照

8行目の解説箇所.cpp
  cin >> str;

入力 参照

11行目の解説箇所.cpp
  for (int i = 0; i < str.size() - 1; i++) {

全体参照

文字列(string型) 文字列の長さ 参照

12行目の解説箇所.cpp
    if (str.at(i) == 'a' && str.at(i+1) == 'b') {

全体参照

文字(char型) 文字列の書き換えと比較 参照

13行目の解説箇所.cpp
      //"ab"を見つけた

全体参照

14行目の解説箇所.cpp
      count++;

複合代入演算子 インクリメントとデクリメント 参照

15行目の解説箇所.cpp
    }

全体参照

16行目の解説箇所.cpp
    else if (str.at(i) == 'b' && str.at(i+1) == 'a') {

全体参照

文字(char型) 文字列の書き換えと比較 参照

22行目の解説箇所.cpp
  if (0 == count) {

if文 参照

23行目の解説箇所.cpp
    cout << "No" << endl;

cout 参照

25行目の解説箇所.cpp
  else {

「前の条件が真でないとき」の処理 else句 参照

28行目の解説箇所.cpp
}

全体参照

main関数 参照

別解

他のページを参考にすることで、提出したコードとは異なるコードでの正解も可能です。

★【工事中】2024年3月までには完成する予定

別解

別解.cpp
別解

別解.cpp

【工事中】別解の最後の方に記載する内容

別解

参照なし

別解.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;
  string str;
  cin >> str;

  if (str.find("ab") != string::npos || str.find("ba") != string::npos) {
    //"ab"または"ba"を見つけた
    cout << "Yes" << endl;
  }
  else
  {
    cout << "No" << endl;
  }
}
別解

別解.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;
  string str;
  cin >> str;

  int count = 0;
  for (int i = 0; i < str.size() - 1; i++) {
    if ('a'+'b' == str.at(i) + str.at(i+1)) {
      //"ab"または"ba"を見つけた
      count++;
    }
  }

  if (0 == count) {
    cout << "No" << endl;
  }
  else {
    cout << "Yes" << endl;
  }
}

デバッグ出力をしたい

コードの途中で、どんな値が入っているか確認したいことがあります。
その方法を説明します。

★【工事中】2024年3月までには完成する予定

【記入中Nをデバッグ出力するコードをかく】
【記入中〇〇の部分がデバッグ出力箇所です】
【記入中出力したいものを色々変えることができることをかく】

修正前のコード

エラーが発生するコード(再掲).cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;
  string str;
  cin >> str;

  int count = 0;
  for (int i = 0; i < str.size(); i++) {
    if (str.at(i) == 'a' && str.at(i+1) == 'b') {
      //"ab"を見つけた
      count++;
    }
    else if (str.at(i) == 'b' && str.at(i+1) == 'a') {
      //"ba"を見つけた
      count++;
    }
  }

  if (0 == count) {
    cout << "No" << endl;
  }
  else {
    cout << "Yes" << endl;
  }
}

エラーメッセージの説明

コードテスト画面でサンプル2を実行すると、以下のエラーが発生します。

エラー画面

このエラーは、以下のページの「注意事項」章の「範囲外エラー」項と同じものです。

デバッグ出力の説明

こんなときは、以下のコードを追加します。

追加するデバッグ出力コード.cpp
    //デバッグ出力 ここから ↓
    cout << "i = " << i << " (" << i+1 << "文字目と" << i+2 << "文字目をチェックする)" << endl;
    cout << "  str.at(" << i+1 << "文字目)=" << str.at(i) << endl;
    cout << ", str.at(" << i+2 << "文字目)=" << str.at(i+1) << endl;
    //デバッグ出力 ここまで ↑

追加後のコードは、以下のとおり。

エラーが発生するコードに、デバッグ出力コードを追加したコード.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n;
  cin >> n;
  string str;
  cin >> str;

  int count = 0;
  for (int i = 0; i < str.size(); i++) {
    //デバッグ出力 ここから ↓
    cout << "i = " << i << " (" << i+1 << "文字目と" << i+2 << "文字目をチェックする)" << endl;
    cout << "  str.at(" << i+1 << "文字目)=" << str.at(i) << endl;
    cout << ", str.at(" << i+2 << "文字目)=" << str.at(i+1) << endl;
    //デバッグ出力 ここまで ↑
    
    if (str.at(i) == 'a' && str.at(i+1) == 'b') {
      //"ab"を見つけた
      count++;
    }
    else if (str.at(i) == 'b' && str.at(i+1) == 'a') {
      //"ba"を見つけた
      count++;
    }
  }

  if (0 == count) {
    cout << "No" << endl;
  }
  else {
    cout << "Yes" << endl;
  }
}

デバッグ出力の結果の説明

コードテストに貼り付けて実行すると、以下のとおり出力されます。

デバッグ出力結果

標準出力欄の内容:
i = 0 (1文字目と2文字目をチェックする)
str.at(1文字目)=b
, str.at(2文字目)=a
i = 1 (2文字目と3文字目をチェックする)
str.at(2文字目)=a
--------ここで途切れている--------

途切れている場所でエラーが発生している可能性が高いので、その辺りをよく見てください。
よく見てみると、入力Sは"ba"の2文字であるにも関わらず、存在しない3文字目をチェックしようとしています。

これはおかしいので、なんやかんや考えて、以下のように修正します。
なんやかんやの部分を知りたい場合は、勉強してから自分でなんやかんや考えてみてください。

修正後のコード

修正後のコード全文は、「文字列の問題を解きたい」の手順4の※以降を参照。

補足:

さまざまなエラーの修正方法を知りたい場合は、以下のページを参照してください。


まとめ

・答える方法や応用力を身に付ける方法、勉強方法は、公式のC++入門ページを見ると良い。
・コードテストを活用すると良い。

募集

・ABCに興味を持ってくれる人。
・AtCoderともだち。

ここまで読んでくださり、ありがとうございます。

次回のABCで会いましょう♪

あなたがABCのA問題を解けるようになってきたときは、AHCでも会いましょう。
以下は、AHC入門記事です。

参考記事

@drken(けんちょん (Otsuki))様

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?