Submission #1360734

#TimeUsernameProblemLanguageResultExecution timeMemory
1360734jbn8Robots (APIO13_robots)C++20
30 / 100
12 ms11616 KiB
#include <ios>
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;

// 0
//1 3
// 2
struct position{
    int x,y;
    explicit operator bool(){
        return x != -1;
    }
    position forward(int dir){
        return position{x+(dir&1)*(dir-2), y+(!(dir&1))*(dir-1)};
    }
    bool operator==(const position& b) const{
        return x == b.x && y == b.y;
    }
    void _print(){
        cout << y << ' ' << x;
    }
    void print(){
        cout << y << ' ' << x << '\n';
    }
};

class Board{
public:
    vector<vector<int>> types;
    vector<vector<vector<position>>> jumps;
    int w, h;
    vector<position> bots;
    int nbBots;
    Board(){}
    Board(int _w, int _h, int _nbBots):
        w(_w),
        h(_h),
        types(_h, vector<int>(_w)),
        jumps(_h, vector<vector<position>>(_w, vector<position>(4, {-1, -1}))),
        nbBots(_nbBots),
        bots(_nbBots){}
    void read(){
        for(int y=0; y<h; y++){
            string line;
            getline(cin, line);
            while(!line.size())getline(cin, line);
            for(int x=0; x<w; x++){
                if(isupper(line[x]))
                    types[y][x] = (line[x] == 'C')+1;
                else if(isalpha(line[x]))
                    types[y][x] = 3;
                else if(isdigit(line[x]))
                    bots[line[x]-'1'] = {x, y};
            }
        }
    }
    int changedir(position pos, int dir){
        if(types[pos.y][pos.x] == 1)
            return (dir+1)&3;
        else if(types[pos.y][pos.x] == 2)
            return (dir-1)&3;
        return dir;
    }
    bool isvalid(position pos){
        return 
            pos.x >= 0 && pos.x < w &&
            pos.y >= 0 && pos.y < h &&
            types[pos.y][pos.x] != 3;
    }
    position jump(position cur, int dir){
        if((bool)jumps[cur.y][cur.x][dir]){
            return jumps[cur.y][cur.x][dir];
        }
        position start = cur;
        int startdir = dir;
        vector<pair<position, int>> stack;
        stack.push_back({cur, dir});
        while(isvalid(cur.forward(dir))){
            cur = cur.forward(dir);
            dir = changedir(cur, dir);
            stack.push_back({cur, dir});
        }
        assert(isvalid(cur));
        for(auto state:stack){
            jumps[state.first.y][state.first.x][state.second] = cur;
        }
        //start._print();cout <<  '(' << startdir << ") -> ";
        //cur.print();
        return cur;
    }
};
int n, w, h;
int MAX;
Board board;
vector<vector<vector<int>>> fromStart;

void bfs(position pos, int id){
    vector<pair<position, int>> Q(w*h);
    int start = 0;
    int end = 0;
    Q[end++] = {pos, 0};
    fromStart[id][pos.y][pos.x] = 0;
    while(start < end){
        auto cur = Q[start++];
        for(int dir=0; dir<4; dir++){
            position nextpos = board.jump(cur.first, dir);
            if(fromStart[id][nextpos.y][nextpos.x] == MAX){
                fromStart[id][nextpos.y][nextpos.x] = cur.second+1;
                Q[end++] = {nextpos, cur.second+1};
            }
        }
    }
}

vector<vector<int>> toGoal;

int dp(position pos, position end){
    if(pos == end)return 0;
    if(toGoal[pos.y][pos.x] != -1)return toGoal[pos.y][pos.x];
    toGoal[pos.y][pos.x] = w*h;
    for(int dir=0; dir<4; dir++){
        int score = dp(pos, end);
        toGoal[pos.y][pos.x] = min(toGoal[pos.y][pos.x], score);
    }
    return toGoal[pos.y][pos.x];
}

int main(){
    ios_base::sync_with_stdio(false);cin.tie(0);
    cin >> n >> w >> h;
    board = Board(w, h, n);
    MAX = n*w*h;
    board.read();
    fromStart.resize(n, vector<vector<int>>(h, vector<int>(w, MAX)));
    //board.jump(board.bots[1], 0).print();
    //board.bots[1].forward(0).print();
    //board.jump(board.bots[3], 1).print();
    //board.jump(board.bots[2], 1).print();
    for(int i=0; i<n; i++){
        bfs(board.bots[i], i);
    }
    int res = w*h*n;
    for(int y=0; y<h; y++){
        for(int x=0; x<w; x++){
            int score = 0;
            for(int i=0; i<n; i++){
                score += fromStart[i][y][x];
            }
            //cout << score << '\t';
            res = min(res, score);
        }
        //cout << '\n';
    }
    if(res >= MAX){
        cout << "-1\n";
    }else
        cout << res << '\n';
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...