ITP1_11_B サイコロ IIをC++で解いてみた[AIZU ONLINE JUDGE]

AIZU ONLINE JUDGE

こんにちは! mnbd(@mnbbbbbd)です。

AIZU ONLINE JUDGEの「ITP1_11_B サイコロ II」を解いてみましたので、その回答と解説をご紹介いたします。

プログラミング初心者なので、もっといい回答があるに違いありません。

あくまでも「動作はする」サンプルとしてご覧ください。

問題文

Dice I と同様の方法で、入力された整数の列からサイコロをつくります。

このサイコロを Dice I の方法で回転させた後の上面と前面の整数が質問として与えられるので、右側の面の整数を答えるプログラムを作成してください。

Input

1行目に各面の整数が、ラベルの順番に空白区切りで与えられます。
2行目に質問の数 qq が与えられます。

続く qq 行に質問が与えられます。各質問では上面と前面の整数が空白区切りで1行に与えられます。

Output

各質問ごとに、サイコロの右側の面の整数を1行に出力してください。

Constraints

0≤0≤ 入力されるサイコロの面の整数 ≤100
入力されるサイコロの面の整数はすべて異なる
1≤q≤24

https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/11/ITP1_11_B

解答

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

struct dice {
    int number[6];
};

struct q_table {
    int first;
    int second;
};

int main() {
    random_device rd;
    mt19937 mt(rd());
    uniform_int_distribution<> rand4(0, 3);
   
    dice d;
    int q_count;

    for(int i = 0; i < 6; i++) {
        cin >> d.number[i];
    }
    cin >> q_count;
    q_table q[q_count];
    for(int i = 0; i < q_count; i++) {
        cin >> q[i].first >> q[i].second;
    }

    for(int i = 0; i < q_count; i++) {
        while(true) {
            string instruction = "SNEW";
            int j = rand4(mt);
            int tmp;

            if(instruction[j] == 'S') {
                // S
                tmp = d.number[0];
                d.number[0] = d.number[4];
                d.number[4] = d.number[5];
                d.number[5] = d.number[1];
                d.number[1] = tmp;
            } else if(instruction[j] == 'E') {
                // E
                tmp = d.number[0];
                d.number[0] = d.number[3];
                d.number[3] = d.number[5];
                d.number[5] = d.number[2];
                d.number[2] = tmp;
            } else if(instruction[j] == 'N') {
                // N
                tmp = d.number[0];
                d.number[0] = d.number[1];
                d.number[1] = d.number[5];
                d.number[5] = d.number[4];
                d.number[4] = tmp;
            } else if(instruction[j] == 'W') {
                // W
                tmp = d.number[0];
                d.number[0] = d.number[2];
                d.number[2] = d.number[5];
                d.number[5] = d.number[3];
                d.number[3] = tmp;
            }

            if(d.number[0] == q[i].first && d.number[1] == q[i].second) {
                cout << d.number[2] << endl;
                break;
            }
        }
    }
    return 0;
}

このコードについて

このコードは動作はしますが、この構造体の使い方が適切だと思いません。

実際にはクラスを書いて関数や変数を持たせたほうがいいです。

これはITP1_11シリーズの問題で共通しています。

最初にサイコロのクラスが書けていれば、その後の問題で一からクラスを書く必要がなくなります。

現時点では書き直してないので、コードの更新はしていませんが、いずれするかもしれません。

ハマったポイント

コードに間違いはなかったのですが、乱数を使用したためにディフォルトのC++の設定ではコンパイルエラーが出てしまいました。

AOJの投稿時に「C++11」を選択すれば問題なく通過できます。

まとめ

AIZU ONLINE JUDGEの「ITP1_11_B サイコロ II」を解いてみましたので、その回答と解説をご紹介いたします。

少しずつですが、プログラミングの勉強をしています。
まだ初心者ですが、よかったらつながっていただけると嬉しいです。
Twitterアカウント(@mnbbbbbd

以上です。
読んでいただきありがとうございました!