35657

Untitled

Jun 18th, 2024 (edited)
428
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.30 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.  
  17. #include <iostream>
  18. #include <vector>
  19.  
  20. struct line {
  21.     int A;
  22.     int B;
  23.     int C;
  24. };
  25.  
  26. struct point {
  27.     int x;
  28.     int y;
  29. };
  30.  
  31. int field_size, max_count, cnt = 0, result = 0;
  32. std::vector<int> row, col;
  33. std::vector<point> points;
  34. std::vector<line> lines;
  35.  
  36. bool check_lines(const int x, const int y) {
  37.     for (const auto& l : lines) {
  38.         if (l.A * x + l.B * y + l.C == 0) {
  39.             return false;
  40.         }
  41.     }
  42.     return true;
  43. }
  44.  
  45. void add_lines(const int x, const int y) {
  46.  
  47.     int A, B, C;
  48.  
  49.     for (const auto& p : points) {
  50.         A = y - p.y;
  51.         B = p.x - x;
  52.         C = p.x * (p.y - y) + p.y * (x - p.x);
  53.         lines.push_back({ A, B, C});
  54.     }
  55. }
  56.  
  57. void get_count(int i = 0, int k = 0) {
  58.     for (int j = k; j < field_size; ++j) {
  59.         if (row[i] < 2 && col[j] < 2 && check_lines(i, j)) {
  60.             if (cnt == max_count - 1) {
  61.                 result++;
  62.                 return;
  63.             }
  64.             else {
  65.                 row[i]++;
  66.                 col[j]++;
  67.                 add_lines(i, j);
  68.                 points.push_back({ i, j });
  69.                 cnt++;
  70.  
  71.                 row[i] == 2 ? get_count(i + 1, 0) : get_count(i, j + 1);
  72.  
  73.                 row[i]--;
  74.                 col[j]--;
  75.                 lines.resize(lines.size() - (points.size() - 1));
  76.                 points.pop_back();
  77.                 cnt--;
  78.             }
  79.         }
  80.     }
  81. }
  82.  
  83. int main() {
  84.  
  85.     setlocale(LC_ALL, "ru");
  86.  
  87.     std::cout << "Введите размер сетки: ";
  88.  
  89.     std::cin >> field_size;
  90.  
  91.     max_count = field_size * 2;
  92.  
  93.     row.resize(field_size);
  94.     col.resize(field_size);
  95.  
  96.     get_count();
  97.  
  98.     std::cout << "В сетке можно расположить максимум " << max_count << " точек" << std::endl;
  99.     std::cout << "Количество расстановок из " << max_count << " точек: " << result << std::endl;
  100.  
  101. }
Advertisement
Add Comment
Please, Sign In to add comment