[白俊13460]仙丹を脱出する2


A.方法


転がり玉は重力で玉を片側に集中させる現象である.従って、左壁の関数と矩形板をそれぞれ90度、180度、270度回転させる関数を実現する.
上記の関数を実現し,DFSおよびすべての状況に対して4方向に傾斜するすべての方向を探索しようとした.このとき、テストボックスだけを回すのにも時間がかかりました.この方法は誤りであり,10回以下の方向があってもDFSで実現すれば最悪の場合には約4^10の探索が行われるからである.また,同じ場合の矩形板を既に目撃していれば,その板の探索には意味がない.

B.実施


vector moveLeft(vector& v)

  • 矩形板の球の関数を左に移動します.
    1-1. '#', '.', '0は変更されません.
    1-2. ビーズを発見した場合、スペースのほかに、詰まった場所を見つけて挿入します.
    1-3. ブラウズ中に穴が見つかったときの成功と失敗を確認します.
  • vector rotateXXX(vector& t)
  • 矩形板を反時計回りに90(1)、180度(2)、270度(3)
  • 回転する.
    void solver(int cnt)

  • BFSによる解凍
    [input]int cnt:何回傾いたか
    3-1:BFS用に用意されたキューから状況の数を取得する.
    3-2:マザーボードが以前に使用された状態であることを確認します.
    3-3:初めて見たボードの場合は、上の1番と2番の関数を使用して、条件に合っているかどうかをナビゲートします.
    3-4:次のソルバ関数でポップアップされたキューをリフレッシュする回数
  • C.コード

    #include <iostream>
    #include <vector>
    #include <queue>
    #include <map>
    
    using namespace std;
    
    int T;
    int N, M;
    int i, j;
    vector<vector<char>> t;
    int answer = 0;
    queue<vector<vector<char>>> q;
    int qs;
    vector<vector<int>> point;
    
    vector<vector<char>> moveLeft(vector<vector<char>>& v) {
        vector<vector<char>> ret;
    
        int goal = 0;
        int i, j, k;
        for(i = 0; i < v.size(); i++) {
            vector<char> tv;
            tv.clear();
            for(j = 0; j < v[i].size(); j++) {
    
                //1-1
                if(v[i][j] == '#' || v[i][j] == '.' || v[i][j] == 'O') {
                    tv.push_back(v[i][j]);
                }
                // red or blue
                else {
                    for(k = tv.size() - 1; k >= 0; k--) {
      		    //1-2
                        if(tv[k] == '#' || tv[k] == 'B' || tv[k] == 'R' || tv[k] == 'O') {
                            //1-3
                            if(tv[k] == 'O') {
                                if(v[i][j] == 'R') {
                                    if(goal == 0)
                                        goal = 1;
                                }
                                else {
                                    goal = -1;
                                }
                            }
                            break;
                        }
                    }
                    if(goal == 0)
                        tv.insert(tv.begin() + k + 1, v[i][j]);
                }
            }
            ret.push_back(tv);
        }
    
        if(goal != 0) {
            ret.clear();
            ret.resize(1);
            if(goal == -1) {
                ret[0].push_back('X');
            }
            else {
                ret[0].push_back('O');
            }
        }
    
        return ret;
    }
    
    vector<vector<char>> rotateOne(vector<vector<char>>& t) {
        vector<vector<char>> ret;
        ret.resize(t[0].size());
        for(int i = 0; i < ret.size(); i++) {
            for(int j = 0; j < t.size(); j++) {
                ret[i].push_back(t[j][t[0].size() - i - 1]);
            }
        }
        return ret;
    }
    
    vector<vector<char>> rotateTwo(vector<vector<char>>& t) {
        vector<vector<char>> ret;
        ret.resize(t.size());
        for(int i = 0; i < ret.size(); i++) {
            for(int j = 0; j < t[0].size(); j++) {
                ret[i].push_back(t[t.size() - i - 1][t[0].size() - j - 1]);
            }
    
        }
        return ret;
    }
    
    vector<vector<char>> rotateThree(vector<vector<char>>& t) {
        vector<vector<char>> ret;
        ret.resize(t[0].size());
        for(int i = 0; i < ret.size(); i++) {
            for(int j = 0; j < t.size(); j++) {
                ret[i].push_back(t[t.size() - j - 1][i]);
            }
    
        }
        return ret;
    }
    
    void solver(int cnt) {
        if(cnt > 10)
            return;
    
        int into = 0;
        for(int x = 0; x < qs; x++) {
            //3-1
            vector<vector<char>> vt = q.front();
            q.pop();
    
            int stop = 0;
            vector<int> pv(4, 0);
            //3-2
            for(int i = 0; i < vt.size();i++) {
                for(int j = 0; j < vt[0].size();j++) {
    
                    if(vt[i][j] == 'R') {
                        pv[0] = i;
                        pv[1] = j;
                    }
                    else if(vt[i][j] == 'B') {
                        pv[2] = i;
                        pv[3] = j;
                    }
                }//cout << endl;
            }
    
            for(int i = 0; i < point.size(); i++) {
                if(point[i][0] == pv[0] && point[i][1] == pv[1] && point[i][2] == pv[2] && point[i][3] == pv[3]) {
                    stop = 1;
                }
            }
            //3-3
            if(stop == 0)
            {
                point.push_back(pv);
                vector<vector<char>> tv1 = moveLeft(vt);
    
                if(tv1.size() == 1) {
                    if(tv1[0][0] == 'O') {
                        answer = cnt;
                        into = 1;
                    }
                }
    
                else {
                    q.push(tv1);
                }
                vector<vector<char>> tv2_1 = rotateOne(vt);
                vector<vector<char>> tv2 = moveLeft(tv2_1);
    
                if(tv2.size() == 1) {
                    if(tv2[0][0] == 'O') {
                        answer = cnt;
                        into = 1;
                    }
                }
    
                else {
                    tv2 = rotateThree(tv2);
                    q.push(tv2);
                }
    
                vector<vector<char>> tv3_1 = rotateTwo(vt);
                vector<vector<char>> tv3 = moveLeft(tv3_1);
    
                if(tv3.size() == 1) {
                    if(tv3[0][0] == 'O') {
                        answer = cnt;
                        into = 1;
                    }
                }
                else {
                    tv3 = rotateTwo(tv3);
                    q.push(tv3);
                }
    
                vector<vector<char>> tv4_1 = rotateThree(vt);
                vector<vector<char>> tv4 = moveLeft(tv4_1);
    
                if(tv4.size() == 1) {
                    if(tv4[0][0] == 'O') {
                        answer = cnt;
                        into = 1;
                    }
                }
    
                else {
                    tv4 = rotateOne(tv4);
                    q.push(tv4);
                }
            }
        }
    
        if(into == 1)
            return;
        //3-4
        qs = q.size();
        solver(cnt + 1);
    
    }
    
    int main() {
    
        //scanf("%d", &T);
    
        T = 1;
        for(int tc = 0; tc < T; tc++) {
            t.clear();
            answer = -1;
    
            while(!q.empty()) {
                q.pop();
            }
    
            point.clear();
    
            scanf("%d %d", &N, &M);
            t.resize(N);
    
            for(i = 0; i < N; i++) {
                for(j = 0; j < M; j++) {
                    char tmp;
                    //scanf("%c ", &tmp);
                    cin >> tmp;
                    t[i].push_back(tmp);
                }
            }
    
            q.push(t);
            qs = q.size();
    
            solver(1);
            printf("%d\n", answer);
        }
    
        return 0;
    }

    D.結果