35657

Untitled

Jun 18th, 2024 (edited)
533
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.79 KB | None | 0 0
  1. /*
  2. Описание алгоритма.
  3. Исходя из условий задания, независимо от размера сетки, в любой линии (горизонтальной, вертикальной, диагональной) можно расположить не более двух узлов. Таким образом, независимо от варианта расстановки узлов, их общее количество не может превышать N * 2.
  4. Наивное решение задачи заключается в переборе всех возможных вариантов расстановки N * 2 узлов в сетке размером N * N, например, для сетки размером 8 * 8 это значение равно числу сочетаний из 64 по 16, то есть 488526937079580.
  5. В данном решении для оптимизации алгоритма использовался поиск с возвратом и кэширование данных.Сетка рассматривается как матрица размером N * N.
  6. Работа функции get_count начинается с поиска места для размещения точки с первого столбца первой строки матрицы.Если в строке и столбце, на пересечении которых находится ячейка, находится не более одного элемента, выполняется проверка функцией check_lines пересечения ячейки матрицы с существующими линиями, образованными любыми двумя точками.
  7. Если точка не пересекается ни с одной линией:
  8. -точка добавляется в массив points;
  9. -по общему уравнению прямой рассчитываются и сохраняются в массиве lines параметры всех линий, образованных добавленной точкой с существующими точками;
  10. -счетчик элементов для соответствующей строки и столбца увеличивается на единицу;
  11. -выполняется рекурсивный запуск функции get_count для поиска места для добавления следующей точки, при этом поиск выполняется со следующего столбца в строке либо с начала следующей строки, если в текущую уже добавлены две точки.
  12. После рекурсивной проверки возможности размещения оставшихся точек, последняя добавленная точка удаляется, линии, образованные ей удаляются, выполняется попытка размещения точки в следующей позиции строки для проверки другого варианта размещения.
  13. Если удалось разместить все N*2 точек, счетчик result увеличивается на единицу, выполняется поиск варианта следующего размещения.
  14. */
  15.  
  16. #include <iostream>
  17. #include <vector>
  18.  
  19. struct line {
  20.     int A;
  21.     int B;
  22.     int C;
  23. };
  24.  
  25. struct point {
  26.     int x;
  27.     int y;
  28. };
  29.  
  30. int field_size, max_count, cnt = 0, result = 0;
  31. std::vector<int> row, col;
  32. std::vector<point> points;
  33. std::vector<line> lines;
  34.  
  35. void print() {
  36.  
  37.     std::vector<std::vector<int>> field(field_size);
  38.  
  39.     for (auto& a : field) {
  40.         a.resize(field_size);
  41.     }
  42.  
  43.     for (const auto& p : points) {
  44.         field[p.x][p.y] = 1;
  45.     }
  46.  
  47.     std::cout << std::endl;
  48.  
  49.     for (int i = 0; i < field_size; ++i) {
  50.         for (int j = 0; j < field_size; ++j) {
  51.             std::cout << field[i][j] << " ";
  52.         }
  53.         std::cout << std::endl;
  54.     }
  55.     std::cout << std::endl;
  56. }
  57.  
  58. bool check_lines(const int x, const int y) {
  59.     for (const auto& l : lines) {
  60.         if (l.A * x + l.B * y + l.C == 0) {
  61.             return false;
  62.         }
  63.     }
  64.     return true;
  65. }
  66.  
  67. void add_lines(const int x, const int y) {
  68.  
  69.     int A, B, C;
  70.  
  71.     for (const auto& p : points) {
  72.         A = y - p.y;
  73.         B = p.x - x;
  74.         C = p.x * (p.y - y) + p.y * (x - p.x);
  75.         lines.push_back({ A, B, C});
  76.     }
  77. }
  78.  
  79. void get_count(int i = 0, int k = 0) {
  80.     for (int j = k; j < field_size; ++j) {
  81.         if (row[i] < 2 && col[j] < 2 && check_lines(i, j)) {
  82.             if (cnt == max_count - 1) {
  83.                 result++;
  84.                 print();
  85.                 return;
  86.             }
  87.             else {
  88.                 row[i]++;
  89.                 col[j]++;
  90.                 add_lines(i, j);
  91.                 points.push_back({ i, j });
  92.                 cnt++;
  93.  
  94.                 row[i] == 2 ? get_count(i + 1, 0) : get_count(i, j + 1);
  95.  
  96.                 row[i]--;
  97.                 col[j]--;
  98.                 lines.resize(lines.size() - (points.size() - 1));
  99.                 points.pop_back();
  100.                 cnt--;
  101.             }
  102.         }
  103.     }
  104. }
  105.  
  106. int main() {
  107.  
  108.     setlocale(LC_ALL, "ru");
  109.  
  110.     std::cout << "Введите размер сетки: ";
  111.  
  112.     std::cin >> field_size;
  113.  
  114.     max_count = field_size * 2;
  115.  
  116.     row.resize(field_size);
  117.     col.resize(field_size);
  118.  
  119.     get_count();
  120.  
  121.     std::cout << "В сетке можно расположить максимум " << max_count << " точек" << std::endl;
  122.     std::cout << "Количество расстановок из " << max_count << " точек: " << result << std::endl;
  123.  
  124. }
Advertisement
Add Comment
Please, Sign In to add comment