- AtCoder Programming Guide for beginners (APG4b)
- M - 1.12.文字列と文字
- N - 1.13.配列
- O - 1.14.STLの関数
- P - 1.15.関数
AtCoder Programming Guide for beginners (APG4b)
M - 1.12.文字列と文字
EX12 - 足したり引いたり / 1.12
模範解答では、1文字ずつスライスして、1の場合は何も処理しないようにしていた。
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// string S; cin >> S; int sum = 1; for (int s_i = 1; s_i < S.size(); s_i+=2) { if (S.at(s_i) == '+') { sum++; } else if (S.at(s_i) == '-') { sum--; } else { cout << "erorr" << endl; break; } } cout << sum << endl; return 0; }
A - 居合を終え、青い絵を覆う / UOIAUAI
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// char c; cin >> c; if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') { cout << "vowel" << endl; } else { cout << "consonant" << endl; } return 0; }
模範解答。 findを使う方法もありとのこと。
https://marycore.jp/prog/cpp/std-string-find-search/#find%EF%BC%8Frfind
std::string s = "a-b-c"; auto pos = s.find("-"); // pos == 1 (先頭から検索) pos = s.rfind("-"); // pos == 3 (末尾から検索) s.find('b'); // 2 (文字型による検索) s.find(std::string("c")); // 4 (std::string型による検索) s.find(""); // 0 s.find("9"); // std::string::npos (見つからなかった場合)
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// char c; cin >> c; const string vowel = "aeiou"; if (vowel.find(c) == string::npos) { cout << "consonant" << endl; } else { cout << "vowel" << endl; } return 0; }
A - AtCoder *** Contest
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// string a, b, c; cin >> a >> b >> c; cout << "A" << b.at(0) << "C" << endl; return 0; }
A - 添字
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// string s; int i; cin >> s >> i; cout << s.at(i-1) << endl; return 0; }
A - お茶
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// string s; cin >> s; int lastCharIndex = int(s.size()) - 1; if (s[lastCharIndex] == 'T') { cout << "YES" << endl; } else { cout << "NO" << endl; } return 0; }
模範解答。方法1は上記の通り。下記の方法もあるそうで。
string s; cin >> s; if (*s.rbegin() == 'T') { cout << "YES" << endl; } else { cout << "NO" << endl; }
B - Minesweeper
回答できず。模範解答を見る。 ・周りのマス目へのオフセット値を定義しておき、forで検索する。 ・数値 + '0' = 数字
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// int numberOfRows, numberOfColumns; cin >> numberOfRows >> numberOfColumns; vector<string> board(50); for (int row_i = 0; row_i < numberOfRows; row_i++) { cin >> board[row_i]; } // 周りのマス目へのオフセット値 const vector<int> offsetOfX = {1,0,-1,0,1,-1,-1,1}; const vector<int> offsetOfY = {0,1,0,-1,1,1,-1,-1}; for (int row_i = 0; row_i < numberOfRows; row_i++) { for (int column_i = 0; column_i < numberOfColumns; column_i++) { if (board.at(row_i).at(column_i) == '#') { continue; } int numberOfAdjacentBombs = 0; for (int around_i = 0; around_i < 8; around_i++) { const int aroundRow = row_i + offsetOfY.at(around_i); const int aroundColumn = column_i + offsetOfX.at(around_i); // 対象のrowが先頭行または最終行のときは無視 if (aroundRow < 0 || numberOfRows - 1 < aroundRow) { continue; } // 対象のcolumnが左端または右端のときは無視 if (aroundColumn < 0 || numberOfColumns - 1 < aroundColumn) { continue; } if (board.at(aroundRow).at(aroundColumn) == '#') { numberOfAdjacentBombs++; } } board.at(row_i).at(column_i) = char(numberOfAdjacentBombs + '0'); // 数値 + '0' = 数字 } } for (int row_i = 0; row_i < numberOfRows; row_i++) { cout << board.at(row_i) << endl; } return 0; }
N - 1.13.配列
配列の使い所 配列とfor文を組み合わせると、大量のデータを扱うプログラムを書くことができます。
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// int N; cin >> N; vector<int> math(N); vector<int> english(N); for (int i = 0; i < N; i++) { cin >> math.at(i); } for (int i = 0; i < N; i++) { cin >> english.at(i); } for (int i = 0; i < N; i++) { cout << math.at(i) + english.at(i) << endl; } return 0; }
EX13 - 平均との差 / 1.13
- 平均は
mean
のほうがaverage
よりも一般的らしい。
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// int numberOfPerson; cin >> numberOfPerson; vector<int> scoresOfAi(1000); int sum = 0; for (int person_i = 0; person_i < numberOfPerson; person_i++) { cin >> scoresOfAi.at(person_i); sum += scoresOfAi.at(person_i); } int average = sum / numberOfPerson; // 結果出力 for (int person_i = 0; person_i < numberOfPerson; person_i++) { cout << abs(scoresOfAi[person_i] - average) << endl; } return 0; }
B - Picture Frame
自分の回答
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// int height, width; cin >> height >> width; vector<string> lines(height); for (int line_i = 0; line_i < height; line_i++) { cin >> lines.at(line_i); } // 上辺 for (int i = 0; i < width + 2; i++) { cout << "#"; } cout << endl; // 中段 for (int line_i = 0; line_i < height; line_i++) { cout << "#" << lines.at(line_i) << "#" << endl; } // 下辺 for (int i = 0; i < width + 2; i++) { cout << "#"; } cout << endl; return 0; }
模範解答
B: Picture Frame最初に,縦H+ 2行,横W+ 2列の文字配列bを用意し,#で埋めておきます.次に,各1iH,1jWごとにai;jをbi+1;j+1へコピーします.最後に,配列bの内容を出力すればよいです.ちなみに,迷路などが入力として与えられたとき,この問題のようにあらかじめ外壁で囲んでおくと,その後の実装が簡単になることがあります
B - Counting Roads
自分のコード。 配列を用意して++していくあれ。解説どおり。
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// int numberOfCities, numberOfRoads; cin >> numberOfCities >> numberOfRoads; vector<int> numberOfRoadsInCityN(numberOfCities); for (int road_i = 0; road_i < numberOfRoads; road_i++) { int startCity, endCity; cin >> startCity >> endCity; numberOfRoadsInCityN.at(startCity-1)++; numberOfRoadsInCityN.at(endCity-1)++; } for (int city_i = 0; city_i < numberOfRoadsInCityN.size(); city_i++) { cout << numberOfRoadsInCityN.at(city_i) << endl; } return 0; }
B - Trained?
諦めて答えを見ました。 イメージとしては連結リストになるんでしょうか。
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// int numberOfButtons; cin >> numberOfButtons; vector<int> buttons(numberOfButtons); for (int button_i = 0; button_i < numberOfButtons; button_i++) { int nextButtonIndex; cin >> nextButtonIndex; nextButtonIndex--; buttons.at(button_i) = nextButtonIndex; } int currentButtonIndex = 0; for (int count = 0;; count++) { if (currentButtonIndex == 1) { // ボタン2が光っている場合 cout << count << endl; break; } // ボタンの数以上にループをしている場合 = ボタン2が押せない場合 if (count >= numberOfButtons) { cout << -1 << endl; break; } currentButtonIndex = buttons.at(currentButtonIndex); } return 0; }
B - Two Colors Card Game
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// // input int numberOfBlueCard; cin >> numberOfBlueCard; vector<string> stringOfBlueCards(numberOfBlueCard); for (int blueCard_i = 0; blueCard_i < numberOfBlueCard; blueCard_i++) { cin >> stringOfBlueCards.at(blueCard_i); } int numberOfRedCard; cin >> numberOfRedCard; vector<string> stringOfRedCards(numberOfRedCard); for (int redCard_i = 0; redCard_i < numberOfRedCard; redCard_i++) { cin >> stringOfRedCards.at(redCard_i); } // process int maxValue = 0; for (int blueCard_i = 0; blueCard_i < numberOfBlueCard; blueCard_i++) { int currentValue = 0; // blueCardの探索 for (int blueCard_j = 0; blueCard_j < numberOfBlueCard; blueCard_j++) { if (stringOfBlueCards.at(blueCard_i) == stringOfBlueCards.at(blueCard_j)) { currentValue++; } } // redCardの探索 for (int redCard_j = 0; redCard_j < numberOfRedCard; redCard_j++) { if (stringOfBlueCards.at(blueCard_i) == stringOfRedCards.at(redCard_j)) { currentValue--; } } maxValue = max(maxValue, currentValue); } cout << maxValue << endl; return 0; }
O - 1.14.STLの関数
C++で用意されている、関数等がまとまっているもののことをSTL (Standard Template Library)といいます。
EX14 - 三人兄弟の身長差 / 1.14
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// vector<int> heightOfPerson(3); cin >> heightOfPerson.at(0) >> heightOfPerson.at(1) >> heightOfPerson.at(2); sort(heightOfPerson.begin(), heightOfPerson.end()); cout << heightOfPerson.at(2) - heightOfPerson.at(0) << endl; return 0; }
模範解答。 max, minの二重構造。
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// int A, B, C; cin >> A >> B >> C; int maximum = max(max(A, B), C); int minimum = min(min(A, B), C); cout << maximum - minimum << endl; return 0; }
B - Card Game for Two
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// int numberOfCards; cin >> numberOfCards; vector<int> cardNumbers(numberOfCards); for (int card_i = 0; card_i < numberOfCards; card_i++) { cin >> cardNumbers.at(card_i); } sort(cardNumbers.begin(), cardNumbers.end()); // 昇順にソート reverse(cardNumbers.begin(), cardNumbers.end()); // 降順に変更 int difference = 0; int sign = 1; for (int card_i = 0; card_i < numberOfCards; card_i++) { difference += sign * cardNumbers.at(card_i); sign *= -1; } cout << difference << endl; return 0; }
回答例。
降順に並べるには、functionalヘッダにあるgreater<型>()を使う。
(i & 1 ? -1 : 1)
これはビット演算の論理積?
#include <iostream> #include <algorithm> #include <functional> using namespace std; int N, a[109]; int main() { cin >> N; for (int i = 0; i < N; i++) cin >> a[i]; sort(a, a + N, greater<int>()); int ret = 0; for (int i = 0; i < N; i++) ret += a[i] * (i & 1 ? -1 : 1); cout << ret << endl; return 0; }
B - Kagami Mochi
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// int numberOfMochi; cin >> numberOfMochi; vector<int> diametersOfMochi(numberOfMochi); for (int mochi_i = 0; mochi_i < numberOfMochi; mochi_i++) { cin >> diametersOfMochi.at(mochi_i); } sort(diametersOfMochi.begin(), diametersOfMochi.end(), greater<int>()); int X = 1; for (int mochi_i = 1; mochi_i < numberOfMochi; mochi_i++) { if (diametersOfMochi.at(mochi_i - 1) == diametersOfMochi.at(mochi_i)) { continue; } X++; } cout << X << endl; return 0; }
模範解答
直径をインデックスに用いる。
flagsの大きさに注意
またはset
を使う方法もある。
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// int N, flags[101]; cin >> N; for (int i = 0; i < N; ++i) { int diameter; cin >> diameter; flags[diameter] = 1; } int ans = 0; for (int i = 0; i < 100; i++) { ans += flags[i]; } cout << ans << endl; return 0; }
P - 1.15.関数
EX15 - 三人兄弟へのプレゼント / 1.15
// main.cpp // CppTest #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; // 1人のテストの点数を表す配列から合計点を計算して返す関数 // 引数 scores: scores.at(i)にi番目のテストの点数が入っている // 返り値: 1人のテストの合計点 int sum(vector<int> scores) { // ここにプログラムを追記 int sumOfScore = 0; for (int score_i = 0; score_i < scores.size(); score_i++) { sumOfScore += scores.at(score_i); } return sumOfScore; } // 3人の合計点からプレゼントの予算を計算して出力する関数 // 引数 sum_a: A君のテストの合計点 // 引数 sum_b: B君のテストの合計点 // 引数 sum_c: C君のテストの合計点 // 返り値: なし void output(int sum_a, int sum_b, int sum_c) { // ここにプログラムを追記 cout << sum_a * sum_b * sum_c << endl; } // ------------------- // ここから先は変更しない // ------------------- // N個の入力を受け取って配列に入れて返す関数 // 引数 N: 入力を受け取る個数 // 返り値: 受け取ったN個の入力の配列 vector<int> input(int N) { vector<int> vec(N); for (int i = 0; i < N; i++) { cin >> vec.at(i); } return vec; } int main(int argc, const char * argv[]) { // input from txt (提出時にこの箇所は削除すること) std::ifstream in("input.txt"); std::cin.rdbuf(in.rdbuf()); ///////////////////// // Write code below / ///////////////////// // 科目の数Nを受け取る int N; cin >> N; // それぞれのテストの点数を受け取る vector<int> A, B, C; A = input(N); B = input(N); C = input(N); // プレゼントの予算を出力 output(sum(A), sum(B), sum(C)); return 0; }