ikeh1024のブログ

ZennやQiitaに書くにはちょっと小粒なネタをこちらに書いています

【学習記録】AtCoder Programming Guide for beginners (APG4b)_01

AtCoder Programming Guide for beginners (APG4b)

B - 1.01.出力とコメント

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

int main() {
  cout << "Hello, world!" << endl;
}
#include <bits/stdc++.h>
using namespace std;

int main() {
  cout << "a";
  cout << "b" << endl;
  cout << "c" << "d" << endl;
}

C - 1.02.プログラムの書き方とエラー

また、元々一行に書いていたプログラムが長くなった場合は、改行してインデントすることがあります。

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

int main() {
  cout << "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    << "abcdefghijklmnopqrstuvwxyz" // 長いので改行してインデント
    << endl;
}

F - 1.05.実行順序と入力

入力を受け取るには cinと>> を使います。

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

int main() {
  int a;

  cin >> a;

  cout << a * 10 << endl;
}

繋げて入力 coutと同じように、cinも>>を繋げて入力を受け取ることが出来ます。

入力が複数ある場合は、スペースか改行で区切られていれば分解して入力してくれます。

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

int main() {
  int a, b, c;
  cin >> a >> b >> c;
  cout << a * b * c << endl;
}

A - New Year

自分の回答

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

int main() {
    int M;  // 12/30のM時
    cin >> M;
    int limitHours = 24 + (24 - M);
    cout << limitHours << endl;
}

模範解答。48から引くほうが効率がいいですね…。

A - Round Up the Mean

自分の回答。むりやり0.99を足してみたが…?

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

int main() {
    int a, b;
    cin >> a >> b;
    double quotient = (a + b) / 2.0;
    int result = quotient + 0.99;
    
    cout << result << endl;
}

模範解答。 小数が出る奇数を偶数にしてしまえばいい、という発想だろう。

#include <iostream>
using namespace std;

int main() {
    int a, b;
    cin >> a >> b;
    cout << (a + b + 1) / 2 << endl;
}

A - Placing Marbles

自分の回答。ゴリゴリ押し。

// input from txt
std::ifstream in("input.txt");
std::cin.rdbuf(in.rdbuf());

int cellsInfo;
cin >> cellsInfo;

int hasBallInFirstPlace  = cellsInfo / 100;
int hasBallInSecondPlace = (cellsInfo - (hasBallInFirstPlace * 100)) / 10;
int hasBallInThirdPlace  = (cellsInfo - hasBallInFirstPlace * 100 - hasBallInSecondPlace * 10);
int result = hasBallInFirstPlace + hasBallInSecondPlace + hasBallInThirdPlace;
cout << result << endl;

模範解答(をCppに書き下してみたもの)。入力を数字ではなく文字列で捉える。

//  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());
    
    string cellsInfo;
    cin >> cellsInfo;
    
    int ballNum = 0;
    if (cellsInfo[0] == '1') {
        ballNum++;
    }
    if (cellsInfo[1] == '1') {
        ballNum++;
    }
    if (cellsInfo[2] == '1') {
        ballNum++;
    }
    
    cout << ballNum << endl;

    return 0;
}

G - 1.06.if文・比較演算子・論理演算子

EX6 - 電卓をつくろう / 1.06

自分のコード。

//  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;
    string op;
    cin >> A >> op >> B;
    
    if (op == "+") {
        cout << A + B << endl;
    } else if (op == "-") {
        cout << A - B << endl;
    } else if (op == "*") {
        cout << A * B << endl;
    } else if (op == "/") {
        if (B == 0) {
            cout << "error" << endl;
        } else {
            cout << A / B << endl;
        }
    } else if (op == "?" || op == "=" || op == "!") {
        cout << "error" << endl;
    }

    return 0;
}

模範解答。elseにerrorをすべて持ってくる書き方を参考にしたい。

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

int main() {
  int A, B;
  string op;
  cin >> A >> op >> B;

  if (op == "+") {
    cout << A + B << endl;
  }
  else if (op == "-") {
    cout << A - B << endl;
  }
  else if (op == "*") {
    cout << A * B << endl;
  }
  else if (op == "/" && B != 0) {
    cout << A / B << endl;
  }
  else {
    cout << "error" << endl;
  }
}

A - Good Integer

自分の回答。index=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 N;
    cin >> N;
    
    if (N[1] == N[2] && ( N[1] == N[0] || N[1] == N[3]) ) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
    
    return 0;
}

模範解答。先頭3つか後ろ3つが等しいかを見ている。

//  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 N;
    cin >> N;
    
    if (N[0] == N[1] && N[1] == N[2]) {
        cout << "Yes" << endl;
    } else if (N[1] == N[2] && N[2] == N[3]) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
    
    return 0;
}

I - 1.08.変数のスコープ

EX8 - たこ焼きセット / 1.08

自分の回答。

//  main.cpp
//  CppTest

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

int main(int argc, const char * argv[]) {

    
    /////////////////////
    // Write code below /
    /////////////////////
    int p = 0;
    int price = 0;
    string text = "";
    
    cin >> p;
    
    // パターン1
    if (p == 1) {
        cin >> price;
    }
    
    // パターン2
    if (p == 2) {
        cin >> text >> price;
        cout << text << "!" << endl;
    }
    
    int N;
    cin >> N;
    
    cout << price * N << endl;
    
    return 0;
}

模範解答。

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

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

  // パターン2
  if (p == 2) {
    string text;
    cin >> text;
    cout << text << "!" << endl;
  }

  int price, N;
  cin >> price >> N;
  cout << price * N << endl;
}

K - 1.10.while文

「N回処理をする」というプログラムをwhile文で書く場合

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

int main() {

  // iを0からはじめる
  int i = 0;

  // iが5未満の間ループ
  while (i < 5) {
    cout << "Hello" << endl;
    i++;
  }

}

L - 1.11.for文・break・continue

EX11 - 電卓をつくろう2 / 1.11

自分の回答。模範解答はforを使っているけどほぼ同じなのでOK。

//  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 numberOfCalculate;
    int A;
    cin >> numberOfCalculate >> A;
    int calculateCount = 0;
    while (calculateCount < numberOfCalculate) {
        string op;  // 演算子
        int B;
        cin >> op;
        cin >> B;
        if (op == "+") {
            A += B;
        } else if (op == "-") {
            A -= B;
        } else if (op == "*") {
            A *= B;
        } else if (op == "/") {
            if (B == 0) {
                cout << "error" << endl;
                break;
            } else {
                A /= B;
            }
        }
        
        cout << calculateCount + 1 << ":" << A << endl;
        calculateCount++;
    }
    return 0;
}

B - Hina Arare

自分の回答。

//  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 numberOfP = 0, numberOfW = 0, numberOfG = 0, numberOfY = 0;
    
    int numberOfHinaarare;
    cin >> numberOfHinaarare;
    for (int indexOfHinaarare = 0; indexOfHinaarare < numberOfHinaarare; indexOfHinaarare++) {
        string colorOfHinaarare;
        cin >> colorOfHinaarare;
        if (colorOfHinaarare == "P") {
            numberOfP++;
        } else if (colorOfHinaarare == "W") {
            numberOfW++;
        } else if (colorOfHinaarare == "G") {
            numberOfG++;
        } else if (colorOfHinaarare == "Y") {
            numberOfY++;
        }
    }
    
    int colorCount = 0;
    if (numberOfP) {
        colorCount++;
    }
    if (numberOfW) {
        colorCount++;
    }
    if (numberOfG) {
        colorCount++;
    }
    if (numberOfY) {
        colorCount++;
    }
    
    if (colorCount == 4) {
        cout << "Four" << endl;
    } else if (colorCount == 3) {
        cout << "Three" << endl;
    } else {
        cout << "error" << endl;
    }
    
    return 0;
}

模範解答。しっかり問題文読もう…。

袋には必ず桃色、白色、緑色のひなあられが入っていることが保証されるので、3種類か4種類かの判別は黄色のひなあられの有無で判別できます。よって、黄色のひなあられがあればFour、なければThreeと出力するとよいです。

模範解答をC++で書いてみた。

//  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 numberOfHinaarare;
    cin >> numberOfHinaarare;
    bool isFour = false; // 黄色があれば4種類
    for (int indexOfHinaarare = 0; indexOfHinaarare < numberOfHinaarare; indexOfHinaarare++) {
        string colorOfHinaarare;
        cin >> colorOfHinaarare;
        if (colorOfHinaarare == "Y") {
            isFour = true;
            break;
        }
    }
    
    if (isFour) {
        cout << "Four" << endl;
    } else {
        cout << "Three" << endl;
    }
    
    return 0;
}

B - Theater

//  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 sumOfPeople  = 0;
    int numberOfGroup;
    cin >> numberOfGroup;
    for (int indexOfGroup = 0; indexOfGroup < numberOfGroup; indexOfGroup++) {
        int startSeat, endSeat;
        cin >> startSeat >> endSeat;
        int numberOfPerson = endSeat - startSeat + 1;
        sumOfPeople += numberOfPerson;
    }
    
    cout << sumOfPeople << endl;
    
    return 0;
}

模範解答。これはOKかな。すべてフラグにする方法も一応頭の片隅に。

li番目からri番目までの連続した席に人が座っているとき、それらはrili+ 1人である。 条件より、同じ席に複数の人が座ることはないので、∑Ni=1(rili+ 1)が答えとなる。よって、これを計算して出力すればよい。 それ以外にも、席数と人数が高々100000なため、席1から席100000までのすべての席において、人がいるかいないかをフラグで持っておき、各iにおいてliからriまでにフラグを立てていく方法でも解くことができる。

B - Harshad Number

文字列をスライスして数値に変換…かと思ったけど、うまくいかず。(char->intができなかった…)模範解答を見るとそんな必要も無いようである。

C++で書くとこんな感じか。

//  main.cpp
//  CppTest

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
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;
    
    int quotient = N; // 商
    int sumOfDigit = 0;
    while (quotient > 0) {
        sumOfDigit += quotient % 10;
        quotient /= 10;
    }
    
    if (N % sumOfDigit == 0) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
    
    return 0;
}

B - Addition and Multiplication

//  main.cpp
//  CppTest

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
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, K;
    cin >> N >> K;
    int currentNumber = 1;  // 初期値
    for (int i = 0; i < N; i++) {
        int numberOfAfterA = currentNumber * 2;
        int numberOfAfterB = currentNumber + K;
        if (numberOfAfterA < numberOfAfterB) {
            currentNumber = numberOfAfterA;
        } else {
            currentNumber = numberOfAfterB;
        }
    }
    
    cout << currentNumber << endl;
    
    return 0;
}

B - Collecting Balls (Easy Version)

ややこしいように思えるけどよく読めば単純。 例題を見てみるのが一番早いか。

//  main.cpp
//  CppTest

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
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 sumOfDistance = 0;
    int N, K;
    cin >> N >> K;
    for (int i = 0; i < N; i++) {
        int x_i;
        cin >> x_i;
        
        int distanceOfRobotA = x_i * 2;
        int distanceOfRobotB = abs(K - x_i) * 2;
        if (distanceOfRobotA < distanceOfRobotB) {
            sumOfDistance += distanceOfRobotA;
        } else {
            sumOfDistance += distanceOfRobotB;
        }
    }
    
    cout << sumOfDistance << endl;
    
    return 0;
}

IMG_218C0424F4ED-1

模範解答。 ・$x_i < K$であることを見るとabsは不要。 ・ifの条件分岐よりmin()のほうが簡潔。 ・数値は最後に2倍すればいい(計算量が減る)

//  main.cpp
//  CppTest

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
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 sumOfDistance = 0;
    int N, K;
    cin >> N >> K;
    for (int i = 0; i < N; i++) {
        int x_i;
        cin >> x_i;
        int distanceOfRobotA = x_i;
        int distanceOfRobotB = K - x_i;
        sumOfDistance += min(distanceOfRobotA, distanceOfRobotB);
    }
    
    cout << sumOfDistance * 2 << endl;
    
    return 0;
}

B - Palindromic Numbers

自分の回答。無駄が多すぎる。

//  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 numberOfPalindrome = 0;
    int A, B;
    cin >> A >> B;
    for (int currentNumber = A; currentNumber < B + 1; currentNumber++) {
        int x[5];
        int buf = currentNumber;
        for (int digit_i = 0; digit_i < 5; digit_i++) {
            x[digit_i] = buf % 10;
            buf /= 10;
        }
        
        int y[5];
        buf = currentNumber;
        for (int digit_i = 4; digit_i >= 0; digit_i--) {
            y[digit_i] = buf % 10;
            buf /= 10;
        }
        
        bool isPalindrome = true;
        for (int i = 0; i < 5; i++) {
            if (x[i] != y[i]) {
                isPalindrome = false;
            }
        }
        
        if (isPalindrome == true) {
            numberOfPalindrome++;
        }
    }
    
    cout << numberOfPalindrome << endl;
    
    return 0;
}

模範解答。 5桁なので真ん中は対象外にして良い。

//  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 numberOfPalindrome = 0;
    int A, B;
    cin >> A >> B;
    
    for (int i = A; i <= B; i++) {
        int s = i % 10;
        int t = i / 10000 % 10;
        int u = i / 10 % 10;
        int v = i / 1000 % 10;
        if (s == t && u == v) {
            numberOfPalindrome++;
        }
    }
    
    cout << numberOfPalindrome << endl;
    
    return 0;
}

B - Shift only

回答できず。模範解答は以下。

$2^{100}$ = 1.2676506e+30

黒板に書いてある整数を管理しておいて,「書かれている整数がすべて偶数である限り」「書かれている整数すべてを2で割る」をシミュレートすればよいです.あるいは,ほとんど同じことですが,最初書かれている整数それぞれに対して「最大で何回2で割れるか」を求め,その最小値をとってもよいです

//  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;
    
    int dmin = 100;
    cin >> N;
    for (int i = 0; i < N; i++) {
        int A;
        cin >> A;
        int d = 0;
        while (A % 2 == 0) {
            A /= 2;
            d++;
        }
        dmin = min(dmin, d);
    }
    cout << dmin << endl;
    
    return 0;
}