Submission details
Task:Labyrintti
Sender:sharph2
Submission time:2025-12-20 18:56:09 +0200
Language:text
Status:READY
Result:0
Feedback
groupverdictscore
#10
Test results
testverdicttimescore
#10.00 s0details

Code

#include <algorithm>
#include <array>
#include <atomic>
#include <fstream>
#include <iostream>
#include <climits>
#include <cmath>
#include <iomanip>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <thread>
#include <vector>

using namespace std;

constexpr int N = 100;
constexpr int C = 26;

vector<vector<int>> T(C);
vector<vector<int>> D(C);
int loss = 0;

vector<string> L(N);
vector<pair<int, int>> pos(C);

void setPos(int i, int r, int c) {
    L[pos[i].first][pos[i].second] = '.';
    pos[i] = {r, c};
    L[pos[i].first][pos[i].second] = 'A' + i;
}

constexpr int TC = 4;
vector<vector<int>> dt[TC];
constexpr int FAR = INT_MAX / 4;

void bfs(int i, vector<vector<int>>& d) {
    d.resize(N);
    for(int i = 0; i < N; ++i) {
        d[i].resize(N);
        fill(d[i].begin(), d[i].end(), FAR);
    }
    queue<pair<int, int>> Q;
    d[pos[i].first][pos[i].second] = 0;
    Q.push(pos[i]);
    while(!Q.empty()) {
        auto [r, c] = Q.front();
        Q.pop();
        for(auto [dr, dc] : array<pair<int, int>, 4>{{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}}) {
            int r2 = r + dr;
            int c2 = c + dc;
            if(L[r2][c2] != '#' && d[r2][c2] == FAR) {
                d[r2][c2] = d[r][c] + 1;
                Q.push({r2, c2});
            }
        }
    }
    for(int j = 0; j < C; ++j) {
        auto [r, c] = pos[j];
        if(d[r][c] < 0) {
            throw 5;
        }
        D[i][j] = d[r][c];
    }
}

void update() {
    vector<thread> threads;
    atomic<int> nextIdx = 0;
    for(int ti = 0; ti < TC; ++ti) {
        threads.emplace_back([ti, &nextIdx]() {
            while(true) {
                int i = nextIdx.fetch_add(1);
                if(i >= C) {
                    break;
                }
                bfs(i, dt[ti]);
            }
        });
    }
    for(thread& t : threads) {
        t.join();
    }
    loss = 0;
    for(int i = 0; i < C; ++i) {
        for(int j = 0; j < C; ++j) {
            if(D[i][j] >= FAR) {
                loss = FAR;
                return;
            }
            loss += abs(D[i][j] - T[i][j]);
            // if(D[i][j] != T[i][j]) {
            //     ++loss;
            // }
        }
    }
}

int main() {
    cin.sync_with_stdio(false);
    cin.tie(nullptr);

    mt19937 rng(1234321);

    ifstream fp("laby.txt");
    for(int i = 0; i < C; ++i) {
        T[i].resize(C);
        D[i].resize(C);
        for(int j = 0; j < C; ++j) {
            fp >> T[i][j];
        }
    }
    if(!fp.good()) throw 5;

    for(int i = 0; i < N; ++i) {
        cin >> L[i];
        if(L[i].size() != N) {
            throw 5;
        }
    }

    for(int i = 0; i < C; ++i) {
        bool found = false;
        for(int r = 0; r < N; ++r) {
            for(int c = 0; c < N; ++c) {
                if((r == 0 || c == 0 || r == N - 1 || c == N - 1) && L[r][c] != '#') {
                    throw 5;
                }
                if(L[r][c] == ('A' + i)) {
                    if(found) {
                        throw 5;
                    }
                    found = true;
                    pos[i] = {r, c};
                }
            }
        }
        if(!found) {
            throw 5;
        }
    }

    {
        update();
        int asd = 0;
        int bsd = 0;
        for(int i = 0; i < C; ++i) {
            for(int j = 0; j < C; ++j) {
                if(T[i][j] == D[i][j]) {
                    ++asd;
                }
                ++bsd;
            }
        }
        cerr << -1 << " " << loss << " " << 100.0 * (double)asd / (double)bsd << "\n";

    }

    for(int iter = 0; ; ++iter) {
        int best = INT_MAX;
        vector<tuple<bool, int, int, int>> bestMoves;
        for(int i = 0; i < C; ++i) {
            auto [r, c] = pos[i];
            for(int dr = -3; dr <= 3; ++dr) {
                for(int dc = -3; dc <= 3; ++dc) {
                    int r2 = r + dr;
                    int c2 = c + dc;
                    if(r2 >= 1 && c2 >= 1 && r2 < N - 1 && c2 < N - 1 && (L[r2][c2] == '.' || L[r2][c2] == '#')) {
                        char old = L[r2][c2];
                        setPos(i, r2, c2);
                        update();
                        if(loss < best) {
                            best = loss;
                            bestMoves.clear();
                        }
                        if(loss == best) {
                            bestMoves.push_back({true, i, r2, c2});
                        }
                        setPos(i, r, c);
                        L[r2][c2] = old;
                    }
                }
            }
            {
                int r2 = uniform_int_distribution<int>(1, N - 2)(rng);
                int c2 = uniform_int_distribution<int>(1, N - 2)(rng);
                if(L[r2][c2] == '.' || L[r2][c2] == '#') {
                    char old = L[r2][c2];
                    setPos(i, r2, c2);
                    update();
                    if(loss < best) {
                        best = loss;
                        bestMoves.clear();
                    }
                    if(loss == best) {
                        bestMoves.push_back({true, i, r2, c2});
                    }
                    setPos(i, r, c);
                    L[r2][c2] = old;
                }
            }
        }
        for(int asd = 0; asd < 100; ++asd) {
            int r = uniform_int_distribution<int>(1, N - 2)(rng);
            int c = uniform_int_distribution<int>(1, N - 2)(rng);
            if(L[r][c] == '#') {
                L[r][c] = '.';
                update();
                if(loss < best) {
                    best = loss;
                    bestMoves.clear();
                }
                if(loss == best) {
                    bestMoves.push_back({false, '.', r, c});
                }
                L[r][c] = '#';
            }
            if(L[r][c] == '.') {
                L[r][c] = '#';
                update();
                if(loss < best) {
                    best = loss;
                    bestMoves.clear();
                }
                if(loss == best) {
                    bestMoves.push_back({false, '#', r, c});
                }
                L[r][c] = '.';
            }
        }
        if(bestMoves.empty()) {
            throw 5;
        }
        auto [t, i, r2, c2] = bestMoves[uniform_int_distribution<int>(0, (int)bestMoves.size() - 1)(rng)];
        if(t) {
            setPos(i, r2, c2);
        } else {
            L[r2][c2] = (char)i;
        }
        update();
        if(loss != best) {
            throw 5;
        }
        int asd = 0;
        int bsd = 0;
        for(int i = 0; i < C; ++i) {
            for(int j = 0; j < C; ++j) {
                if(T[i][j] == D[i][j]) {
                    ++asd;
                }
                ++bsd;
            }
        }
        cerr << iter << " " << best << " " << 100.0 * (double)asd / (double)bsd << "\n";
        if(iter % 20 == 0) {
            cerr << "SAVE\n";
            ofstream fp("labyrintti2.out");
            for(int i = 0; i < N; ++i) {
                fp << L[i] << "\n";
            }
            fp.close();
        }
    }

    return 0;
}

Test details

Test 1

Verdict:

input
0 219 39 206 143 151 40 68 214...

correct output
(empty)

user output
#include <algorithm>
#include <array>
#include <atomic>
#include <fstream>
#include <iostream>
...