Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- using ll = long long;
- using ld = long double;
- char fieldname[20], outname[20];
- ifstream field;
- ofstream out;
- int h, w;
- char grid[200][200], best_grid[200][200];
- char vis[200][200];
- pair<int,int> sizes[]{
- {6, 10},
- {100, 100},
- {100, 100},
- {100, 100},
- {100, 100},
- {11, 11},
- {20, 20},
- {20, 20},
- {11, 21},
- {200, 200},
- };
- pair<int,int> dd[]{{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
- mt19937 rng(122);
- const ld alpha = 0.9999999;
- const ld t0 = 2.5;
- ld t = t0;
- int score() {
- pair<int,int> e;
- for (int i = 0; i < h; i++) {
- if (grid[i][0] == '.') e = {i, 0};
- if (grid[i][w-1] == '.') e = {i, w-1};
- }
- for (int i = 0; i < w; i++) {
- if (grid[0][i] == '.') e = {0, i};
- if (grid[h-1][i] == '.') e = {h-1, i};
- }
- for (int i = 0; i < h; i++)
- memset(vis, 0, sizeof(*vis) * w);
- queue<tuple<int,int,int>> bfs;
- bfs.push({e.first, e.second, 1});
- vis[e.first][e.second] = 1;
- int res = 0;
- while (bfs.size()) {
- auto [i, j, dep] = bfs.front();
- bfs.pop();
- res = dep;
- for (int d = 0; d < 4; d++) {
- int ni = i + dd[d].first;
- int nj = j + dd[d].second;
- if (ni < 0 || ni >= h || nj < 0 || nj >= w || grid[ni][nj] != '.')
- continue;
- if (!vis[ni][nj]) {
- vis[ni][nj] = 1;
- bfs.push({ni, nj, dep+1});
- }
- }
- }
- return res;
- }
- bool accept(int newEnergy, int oldEnergy) {
- if (newEnergy >= oldEnergy) {
- return 1;
- }
- uniform_real_distribution<ld> dist;
- return dist(rng) < exp((newEnergy - oldEnergy) / t);
- }
- void input() {
- field.close();
- field.clear();
- field.open(fieldname);
- for (int i = 0; i < h; i++)
- for (int j = 0; j < w; j++)
- field >> grid[i][j];
- }
- void output(char grid[200][200]) {
- out.close();
- out.clear();
- out.open(outname);
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- assert(grid[i][j] == '.' || grid[i][j] == '#' || grid[i][j] == 'X');
- out << grid[i][j];
- }
- out << '\n';
- }
- out << flush;
- }
- void run() {
- uniform_int_distribution<int> row(0, h-1), col(0, w-1);
- int every = 1;
- while (every < h * w) every *= 2;
- every = (1 << 27) / every;
- int best_score = 0;
- while (true) {
- t = t0;
- input();
- int prev_score = score();
- pair<int,int> e{0, 1};// this is always non-X
- grid[0][1] = '.';
- for (int i = 1; i < h-1; i++) {
- for (int j = 1; j < w-1; j++) {
- if (grid[i][j] != 'X') {
- grid[i][j] = rng() % 5 < 3 ? '.' : '#';
- }
- }
- }
- for (ll step = 0; t >= 0.15; step++) {
- pair<int,int> pe{-1, -1};
- int i, j;
- while (true) {
- i = row(rng);
- j = col(rng);
- if (grid[i][j] == 'X')
- continue;
- if (i == 0 || i == h-1 || j == 0 || j == w-1) {
- if (grid[i][j] != '.') {
- grid[e.first][e.second] = '#';
- grid[i][j] = '.';
- pe = e;
- e = {i, j};
- break;
- }
- }
- else {
- if (grid[i][j] == '.')
- grid[i][j] = '#';
- else grid[i][j] = '.';
- break;
- }
- }
- int cur_score = score();
- if (cur_score > best_score) {
- best_score = cur_score;
- memcpy(best_grid, grid, sizeof(grid));
- }
- if (accept(cur_score, prev_score)) {
- prev_score = cur_score;
- } else {
- if (pe.first >= 0) {
- grid[pe.first][pe.second] = '.';
- grid[e.first][e.second] = '#';
- e = pe;
- } else {
- if (grid[i][j] == '.')
- grid[i][j] = '#';
- else grid[i][j] = '.';
- }
- }
- t = t * alpha;
- if ((step & (every -1)) == 0) {
- cout << step << ' ' << t << ' ' << prev_score << ' ' << best_score << endl;
- output(best_grid);
- }
- }
- }
- }
- void on_interrupt(int s){
- printf("Caught signal %d\n", s);
- output(best_grid);
- exit(1);
- }
- signed main() {
- cin.tie(0)->sync_with_stdio(0);
- int t;
- cin >> t;
- sprintf(fieldname, "field%X.txt", t);
- sprintf(outname, "maze%X.txt", t);
- cout << fieldname << ' ' << outname << endl;
- tie(h, w) = sizes[t - 1];
- signal(SIGINT, on_interrupt);
- run();
- output(best_grid);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement