[白俊17780新ゲーム]


A.方法


回答時間:約1時間40分...(ミスでなければ1時間20分くらい解けたかな)
実装とシミュレーションカテゴリを用いて問題指紋にソースコードを充実させて記述すれば,正解が得られる.

B.実施


nxtcan(int x, int y)
(x,y)のセルがどのセルの関数であるかを判別する.
mov(int x, int y)
(x,y)の馬移動関数.転送中に4つ以上の重複語がある場合はtrueを返し、そうでない場合はfalseを返します.
ミスで時間が遅れたところは次のコードです.
for(int k = 0; k < K; k++) {
        for(int i = 0 ; i < N; i++) {
            for(int j = 0; j < N; j++) {
                if(pan[i][j].size() > 0 && pan[i][j][0].first == k) {
                    if(mov(i, j))
                        return time;
                    break;
                }
            }
        }
    }
kは馬の番号,i,jはメッシュの位置であり,ゲートが条件を満たしmov関数で一度移動すれば,その馬kに対して探索を終了すべきであるが,そうではない.(i,j)中のkが(i+1,j)に移動し、その後iが増加し、(i+1,j)の一番下の馬がkであれば、k馬は1ラウンドに2回以上移動する.
次は修正されたコードです.
for(int k = 0; k < K; k++) {
        chk = 0;
        for(int i = 0 ; i < N; i++) {
            for(int j = 0; j < N; j++) {
                if(pan[i][j].size() > 0 && pan[i][j][0].first == k) {
                    if(mov(i, j))
                        return time;
                    chk = 1;
                    break;
                }
            }
            if(chk == 1)
                break;
        }
    }

C.コード

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;
int T, N, K;
vector<vector<int>> table;
vector<vector<vector<pair<int, int>>>> pan;
int dx[4] = {0,0,-1,1};
int dy[4] = {1,-1,0,0};
int nxtcan(int x, int y) {
    if(x < 0 || x >= N || y < 0 || y >= N)
        return 2;
    if(table[x][y] == 0)
        return 0;
    else if(table[x][y] == 1)
        return 1;
    else if(table[x][y] == 2)
        return 2;
    else{return -1;}
}
bool mov(int x, int y) {

    int d = pan[x][y][0].second;

    int nx = x + dx[d];
    int ny = y + dy[d];
    int ncan = nxtcan(nx, ny);

    if(ncan == 0) {

        for(auto it: pan[x][y])
            pan[nx][ny].push_back(it);
        pan[x][y].clear();

        if(pan[nx][ny].size() >= 4)
            return true;
    }
    else if(ncan == 1) {
        reverse(pan[x][y].begin(), pan[x][y].end());
        for(auto it: pan[x][y])
            pan[nx][ny].push_back(it);
        pan[x][y].clear();

        if(pan[nx][ny].size() >= 4)
            return true;
    }
    else if(ncan == 2) {

        if(pan[x][y][0].second == 0)
            pan[x][y][0].second = 1;
        else if(pan[x][y][0].second == 1)
            pan[x][y][0].second = 0;
        else if(pan[x][y][0].second == 2)
            pan[x][y][0].second = 3;
        else if(pan[x][y][0].second == 3)
            pan[x][y][0].second = 2;

        d = pan[x][y][0].second;


        nx = x + dx[d];
        ny = y + dy[d];
        ncan = nxtcan(nx, ny);
        if(ncan == 0) {

            for(auto it: pan[x][y])
                pan[nx][ny].push_back(it);
            pan[x][y].clear();

            if(pan[nx][ny].size() >= 4)
                return true;
        }
        else if(ncan == 1) {
            reverse(pan[x][y].begin(), pan[x][y].end());
            for(auto it: pan[x][y])
                pan[nx][ny].push_back(it);
            pan[x][y].clear();

            if(pan[nx][ny].size() >= 4)
                return true;
        }
        else if(ncan == 2) {
            // do nothing
            return false;
        }
        else {return false;}
    }
    else {return false;}
    return false;
}
int solver(int time) {

    if(time > 1000)
        return -1;

    int chk;
    for(int k = 0; k < K; k++) {
        chk = 0;
        for(int i = 0 ; i < N; i++) {
            for(int j = 0; j < N; j++) {
                if(pan[i][j].size() > 0 && pan[i][j][0].first == k) {
                    if(mov(i, j))
                        return time;
                    chk = 1;
                    break;
                }
            }
            if(chk == 1)
                break;
        }
    }
    return solver(time+1);
}
int main() {

    //scanf("%d", &T);
    T = 1;
    for(int tc = 0; tc < T; tc++) {
        scanf("%d %d", &N, &K);
        table.clear();
        table.resize(N);
        pan.clear();
        pan.resize(N);

        for(int i = 0 ; i < N; i++) {
            table[i].resize(N);
            pan[i].resize(N);
            for(int j = 0; j < N; j++) {
                scanf("%d", &table[i][j]);
            }
        }
        for(int i = 0; i < K; i++) {
            int a, b, c;
            scanf("%d %d %d", &a, &b, &c);

            pan[a-1][b-1].push_back(make_pair(i, c-1));

        }
        cout << solver(1) << endl;
    }
    return 0;
}

D.結果