Advertisement
Guest User

Untitled

a guest
Aug 3rd, 2023
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.99 KB | Source Code | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. using ll = long long;
  5. using ld = long double;
  6.  
  7. char fieldname[20], outname[20];
  8. ifstream field;
  9. ofstream out;
  10.  
  11. int h, w;
  12. char grid[200][200], best_grid[200][200];
  13. char vis[200][200];
  14. pair<int,int> sizes[]{
  15.     {6, 10},
  16.     {100, 100},
  17.     {100, 100},
  18.     {100, 100},
  19.     {100, 100},
  20.     {11, 11},
  21.     {20, 20},
  22.     {20, 20},
  23.     {11, 21},
  24.     {200, 200},
  25. };
  26.  
  27. pair<int,int> dd[]{{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
  28. mt19937 rng(122);
  29. const ld alpha = 0.9999999;
  30. const ld t0 = 2.5;
  31. ld t = t0;
  32.  
  33. int score() {
  34.     pair<int,int> e;
  35.     for (int i = 0; i < h; i++) {
  36.         if (grid[i][0] == '.') e = {i, 0};
  37.         if (grid[i][w-1] == '.') e = {i, w-1};
  38.     }
  39.     for (int i = 0; i < w; i++) {
  40.         if (grid[0][i] == '.') e = {0, i};
  41.         if (grid[h-1][i] == '.') e = {h-1, i};
  42.     }
  43.  
  44.     for (int i = 0; i < h; i++)
  45.         memset(vis, 0, sizeof(*vis) * w);
  46.  
  47.     queue<tuple<int,int,int>> bfs;
  48.     bfs.push({e.first, e.second, 1});
  49.     vis[e.first][e.second] = 1;
  50.     int res = 0;
  51.     while (bfs.size()) {
  52.         auto [i, j, dep] = bfs.front();
  53.         bfs.pop();
  54.         res = dep;
  55.         for (int d = 0; d < 4; d++) {
  56.             int ni = i + dd[d].first;
  57.             int nj = j + dd[d].second;
  58.             if (ni < 0 || ni >= h || nj < 0 || nj >= w || grid[ni][nj] != '.')
  59.                 continue;
  60.             if (!vis[ni][nj]) {
  61.                 vis[ni][nj] = 1;
  62.                 bfs.push({ni, nj, dep+1});
  63.             }
  64.         }
  65.     }
  66.     return res;
  67. }
  68.  
  69. bool accept(int newEnergy, int oldEnergy) {
  70.     if (newEnergy >= oldEnergy) {
  71.         return 1;
  72.     }
  73.     uniform_real_distribution<ld> dist;
  74.     return dist(rng) < exp((newEnergy - oldEnergy) / t);
  75. }
  76.  
  77. void input() {
  78.     field.close();
  79.     field.clear();
  80.     field.open(fieldname);
  81.  
  82.     for (int i = 0; i < h; i++)
  83.         for (int j = 0; j < w; j++)
  84.             field >> grid[i][j];
  85. }
  86. void output(char grid[200][200]) {
  87.     out.close();
  88.     out.clear();
  89.     out.open(outname);
  90.     for (int i = 0; i < h; i++) {
  91.         for (int j = 0; j < w; j++) {
  92.             assert(grid[i][j] == '.' || grid[i][j] == '#' || grid[i][j] == 'X');
  93.             out << grid[i][j];
  94.         }
  95.         out << '\n';
  96.     }
  97.     out << flush;
  98. }
  99.  
  100. void run() {
  101.     uniform_int_distribution<int> row(0, h-1), col(0, w-1);
  102.     int every = 1;
  103.     while (every < h * w) every *= 2;
  104.     every = (1 << 27) / every;
  105.  
  106.     int best_score = 0;
  107.  
  108.     while (true) {
  109.         t = t0;
  110.         input();
  111.  
  112.         int prev_score = score();
  113.         pair<int,int> e{0, 1};// this is always non-X
  114.         grid[0][1] = '.';
  115.  
  116.         for (int i = 1; i < h-1; i++) {
  117.             for (int j = 1; j < w-1; j++) {
  118.                 if (grid[i][j] != 'X') {
  119.                     grid[i][j] = rng() % 5 < 3 ? '.' : '#';
  120.                 }
  121.             }
  122.         }
  123.  
  124.         for (ll step = 0; t >= 0.15; step++) {
  125.             pair<int,int> pe{-1, -1};
  126.             int i, j;
  127.             while (true) {
  128.                 i = row(rng);
  129.                 j = col(rng);
  130.                 if (grid[i][j] == 'X')
  131.                     continue;
  132.                 if (i == 0 || i == h-1 || j == 0 || j == w-1) {
  133.                     if (grid[i][j] != '.') {
  134.                         grid[e.first][e.second] = '#';
  135.                         grid[i][j] = '.';
  136.                         pe = e;
  137.                         e = {i, j};
  138.                         break;
  139.                     }
  140.                 }
  141.                 else {
  142.                     if (grid[i][j] == '.')
  143.                         grid[i][j] = '#';
  144.                     else grid[i][j] = '.';
  145.                     break;
  146.                 }
  147.             }
  148.  
  149.             int cur_score = score();
  150.             if (cur_score > best_score) {
  151.                 best_score = cur_score;
  152.                 memcpy(best_grid, grid, sizeof(grid));
  153.             }
  154.  
  155.             if (accept(cur_score, prev_score)) {
  156.                 prev_score = cur_score;
  157.             } else {
  158.                 if (pe.first >= 0) {
  159.                     grid[pe.first][pe.second] = '.';
  160.                     grid[e.first][e.second] = '#';
  161.                     e = pe;
  162.                 } else {
  163.                     if (grid[i][j] == '.')
  164.                         grid[i][j] = '#';
  165.                     else grid[i][j] = '.';
  166.                 }
  167.             }
  168.             t = t * alpha;
  169.  
  170.             if ((step & (every -1)) == 0) {
  171.                 cout << step << ' ' << t <<  ' ' << prev_score << ' ' << best_score << endl;
  172.                 output(best_grid);
  173.             }
  174.         }
  175.     }
  176. }
  177.  
  178. void on_interrupt(int s){
  179.     printf("Caught signal %d\n", s);
  180.     output(best_grid);
  181.     exit(1);
  182. }
  183.  
  184. signed main() {
  185.     cin.tie(0)->sync_with_stdio(0);
  186.     int t;
  187.     cin >> t;
  188.     sprintf(fieldname, "field%X.txt", t);
  189.     sprintf(outname, "maze%X.txt", t);
  190.  
  191.     cout << fieldname << ' ' << outname << endl;
  192.  
  193.     tie(h, w) = sizes[t - 1];
  194.     signal(SIGINT, on_interrupt);
  195.  
  196.     run();
  197.     output(best_grid);
  198. }
  199.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement