Advertisement
Mlxa

Визуальный Коммивояжёр

Jun 23rd, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.79 KB | None | 0 0
  1. #define map std_map
  2. #include <bits/stdc++.h>
  3. #include <SFML/Graphics.hpp>
  4. #include <SFML/Window/ContextSettings.hpp>
  5. #include <SFML/System/Time.hpp>
  6. using namespace std;
  7. using namespace sf;
  8. #undef map
  9.  
  10. RenderWindow window;
  11.  
  12. const double I = 1.0 / 0.0;
  13. const double X = 932;
  14. const double Y = 932;
  15.  
  16. void check_event() {
  17.     Event event;
  18.     while (window.pollEvent(event)) {
  19.         if (event.type == Event::Closed) {
  20.             window.close();
  21.         }
  22.     }
  23. }
  24.  
  25.  
  26. void draw_point(int x, int y, Color c) {
  27.     VertexArray pix(sf::Points, 1);
  28.     pix[0].position = Vector2f(x, y);
  29.     pix[0].color = c;
  30.     window.draw(pix);
  31. }
  32.  
  33. void draw_square(int x, int y, Color c) {
  34.     const int S = 4;
  35.     for (int i = 0; i < S; ++i) {
  36.         for (int j = 0; j < S; ++j) {
  37.             draw_point(22 + S * x + i, 22 + S * y + j, c);
  38.         }
  39.     }
  40. }
  41.  
  42. void draw_line(int a, int b, int c, int d) {
  43.     VertexArray l(sf::Lines, 2);
  44.     l[0].position = Vector2f(a, b);
  45.     l[1].position = Vector2f(c, d);
  46.     l[0].color    = {0, 0, 0};
  47.     l[1].color    = {0, 0, 0};
  48.     window.draw(l);
  49. }
  50.  
  51. void draw_circle(int x, int y, int r, Color c) {
  52.     CircleShape a;
  53.     a.setPosition(x - r, y - r);
  54.     a.setRadius(r);
  55.     a.setFillColor(c);
  56.     a.setOutlineThickness(1);
  57.     a.setOutlineColor(Color::Black);
  58.     window.draw(a);
  59. }
  60.  
  61. const int N = 20;
  62.  
  63. const char map[52][53] = {
  64. ".............##..................##....#...#........",
  65. "......#......##.....#..#...................##..#....",
  66. ".......#.....##..#.#.......##.......................",
  67. ".........#########............#.................#...",
  68. ".####.#########.##..##....#....#...................#",
  69. ".#.###########.#.#............#.........#.#.....#..#",
  70. "##.##############.#....##......................#....",
  71. ".########....#..#..........#........#...#.#....#....",
  72. "........##..##....#..#..##.#.#............#.#.......",
  73. "...#........##....#....#..#.....#.......##..........",
  74. "............##..................#...#....#..........",
  75. "............##....#..........#..##................#.",
  76. "...........##..#................#..........#......#.",
  77. "............###...#..#..##....#...........#.........",
  78. "....#......######...........#...........###..#...##.",
  79. "...........#####.#........#................#.......#",
  80. "...........###...#...#...........#..................",
  81. "........#..#..#..##........#....##.....##...#.#.....",
  82. ".........#...##..###............###.#.....#.........",
  83. ".....#...#....#.#...#........#..##..#...#......#....",
  84. "..............####...#..#....####..........#........",
  85. "..#.........#...###.......###.######.....#..........",
  86. "..#......#.#...#.###.......#######...#.#............",
  87. "........####......##..#.#.....####...........#..#.#.",
  88. "...###...##.....#..#.........#.##....#...#...##.#...",
  89. "................#..............##...................",
  90. "..#...............#...#..#.#...###.....#............",
  91. "...........#................#..###.........#......#.",
  92. "..#..#.....................#.#.##...#.#.........#...",
  93. "#.#......##..#................###.#........#...##...",
  94. "..#..#....#...#.#............#####.....#..#....#....",
  95. "..................#........######..........#........",
  96. "................#.......#..###.....#...#..........#.",
  97. "....#...........#....#.....##.......................",
  98. "#...#.....#...............##..........##......#.....",
  99. "......#.....#.#..........###..#..#....#...#........#",
  100. ".#......................###........#.#...#..........",
  101. "........#..#..#..........##...###....#........#...#.",
  102. ".#.#....................#.#....#..........##.....#..",
  103. ".......#......#......#..........#...#.............#.",
  104. ".................#.#...........#.#..................",
  105. "..#...............#..................#....##......##",
  106. ".....#.........#..............#......#.#..........##",
  107. "..#.#########.#####...........#....#..##............",
  108. "....####.##########...........#.##.....#.....#.....#",
  109. "....................#.......##..##.....#....#.......",
  110. ".#...............................##...............##",
  111. "..................#......#.......##...#...........#.",
  112. ".....................#.#.........##..#..............",
  113. ".#........#.#.##.#.#........#.....##............#...",
  114. "..#..#................#......#..#.##.#..##...#......",
  115. "....#.....#..#...#........#.....#..#...#...##......."};
  116.  
  117. const char alphabet[53] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  118.  
  119. string str_coords(int i, int j) {
  120.     return alphabet[j] + to_string(52 - i);
  121. }
  122.  
  123. int decode(char x) {
  124.     if ('a' <= x && x <= 'z') {
  125.         return x - 'a';
  126.     } else {
  127.         return 26 + x - 'A';
  128.     }
  129. }
  130.  
  131. double get_dist(string a, string b) {
  132.     int di = decode(a[0]) - decode(b[0]);
  133.     int dj = stoi(a.substr(1)) - stoi(b.substr(1));
  134.     return hypot(di, dj);
  135. }
  136.  
  137. set<pair<pair<int, int>, pair<int, int>>> edges;
  138.  
  139. bool ok(int i) {
  140.     return 0 <= i && i < N;
  141. }
  142.  
  143. void almost_sleep() {
  144.     clock_t fn = clock() + CLOCKS_PER_SEC / 10;
  145.     while (clock() < fn) {
  146.         ;
  147.     }
  148. }
  149.  
  150. void iteration() {
  151.     for (int i = 0; i < N; ++i) {
  152.         for (int j = 0; j < N; ++j) {
  153.             if (map[i][j] != '#') {
  154.                 continue;
  155.             }
  156.             draw_circle(50 + 16 * j, 50 + 16 * i, 6, Color::White);
  157.         }
  158.     }
  159.     for (auto ppa : edges) {
  160.         int a, b, c, d;
  161.         tie(a, b) = ppa.first;
  162.         tie(c, d) = ppa.second;
  163.         draw_line(50 + 16 * b, 50 + 16 * a, 50 + 16 * d, 50 + 16 * c);
  164.     }
  165.     window.display();
  166.     cerr << "First tap" << endl;
  167.     while (!Mouse::isButtonPressed(Mouse::Left)) {
  168.         ;
  169.     }
  170.     sleep(seconds(0.2));
  171.     auto vec = sf::Mouse::getPosition(window);
  172.     int b = (vec.x - 50 + 8) / 16;
  173.     int a = (vec.y - 50 + 8) / 16;
  174.     if (!ok(a) || !ok(b) || map[a][b] != '#') {
  175.         return;
  176.     }
  177.     cerr << "Second tap" << endl;
  178.     while (!Mouse::isButtonPressed(Mouse::Left)) {
  179.         ;
  180.     }
  181.     sleep(seconds(0.5));
  182.     vec = sf::Mouse::getPosition(window);
  183.     int d = (vec.x - 50 + 8) / 16;
  184.     int c = (vec.y - 50 + 8) / 16;
  185.     window.display();
  186.     if (!ok(c) || !ok(d) || map[c][d] != '#') {
  187.         return;
  188.     }
  189.     if (a == c && b == d) {
  190.         return;
  191.     }
  192.     cerr << "Xor: (" << a << ", " << b << ") -> (" << c << ", " << d << ")" << endl;
  193.     pair<int, int> ab(a, b);
  194.     pair<int, int> cd(c, d);
  195.     if (ab > cd) {
  196.         swap(ab, cd);
  197.     }
  198.     assert(ab < cd);
  199.     pair<pair<int, int>, pair<int, int>> abcd(ab, cd);
  200.     if (edges.count(abcd)) {
  201.         edges.erase(abcd);
  202.     } else {
  203.         edges.insert(abcd);
  204.     }
  205. }
  206.  
  207. int main() {   
  208.     ContextSettings settings;
  209.     settings.antialiasingLevel = 8;
  210.     window.create(VideoMode(X, Y), "Main window", Style::Default, settings);
  211.    
  212.     int psize = 0;
  213.     for (int i = 0; i < N; ++i) {
  214.         for (int j = 0; j < N; ++j) {
  215.             psize += map[i][j] == '#';
  216.         }
  217.     }
  218.    
  219.     while (window.isOpen()) {
  220.         check_event();
  221.         window.clear(Color::White);
  222.         iteration();
  223.         window.display();
  224.         sleep(seconds(0.1));
  225.         cout << edges.size() << " / " << psize - 1 << " edges" << endl;
  226.         std_map<pair<int, int>, int> cnt;
  227.         for (auto ppa : edges) {
  228.             ++cnt[ppa.first];
  229.             ++cnt[ppa.second];
  230.         }
  231.         pair<int, int> start(-1, -1);
  232.         for (auto pa : cnt) {
  233.             if (pa.second == 1) {
  234.                 start = pa.first;
  235.             }
  236.         }
  237.         if (start.first == -1) {
  238.             continue;
  239.         }
  240.         set<pair<int, int>> used    = {start};
  241.         vector<string> path         = {str_coords(start.first, start.second)};
  242.        
  243.         while (1) {
  244.             bool run = false;
  245.             for (auto ppa : edges) {
  246.                 if (ppa.first != start || used.count(ppa.second)) {
  247.                     swap(ppa.first, ppa.second);
  248.                 }
  249.                 if (ppa.first != start || used.count(ppa.second)) {
  250.                     continue;
  251.                 }
  252.                 start = ppa.second;
  253.                 used.insert(start);
  254.                 path.push_back(str_coords(start.first, start.second));
  255.                 run = true;
  256.             }
  257.             if (!run) {
  258.                 break;
  259.             }
  260.         }
  261.         if ((int)path.size() != psize) {
  262.             cout << "Wrong len (" << path.size() << ")" << endl;
  263.             continue;
  264.         }
  265.         cout << "Path:" << endl;
  266.         double sum = 0;
  267.         for (auto e : path) {
  268.             cout << e << " ";
  269.         }
  270.         cout << endl;
  271.         for (int i = 0; i + 1 < (int)path.size(); ++i) {
  272.             sum += get_dist(path[i], path[i + 1]);
  273.         }
  274.         cout << "Sum = " << sum << endl;       
  275.     }
  276.  
  277.     return 0;
  278. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement