Argent007

Задачи про Васю

Mar 22nd, 2023 (edited)
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.35 KB | None | 0 0
  1. // ConsoleApplication1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <fstream>
  9. #include <numeric>
  10. #include <functional>
  11.  
  12. using graph = std::vector<std::vector<int>>;
  13. using std::vector;
  14.  
  15. //базовый поиск в ширину
  16. void BFS(const graph& g, int s, vector<int>& d, vector<int>& p, bool need_init = true)
  17. {
  18.     int infty = g.size();
  19.     if (need_init)
  20.     {
  21.         d.assign(g.size(), infty);
  22.         p.assign(g.size(), -1);
  23.     }
  24.     d[s] = 0;
  25.     std::queue<int> Q;
  26.     Q.push(s);
  27.     while (Q.size())
  28.     {
  29.         auto u = Q.front();
  30.         Q.pop();
  31.         for (auto v : g[u])
  32.         {
  33.             if (d[v] == infty)
  34.             {
  35.                 d[v] = d[u] + 1;
  36.                 p[v] = u;
  37.                 Q.push(v);
  38.             }
  39.         }
  40.     }
  41. }
  42.  
  43. vector<int> vertices_from_shortest_path(const graph& g, int a, int b)
  44. {
  45.     int infty = g.size();
  46.     vector<int> da, db, p;
  47.     BFS(g, a, da, p, true);
  48.     BFS(g, b, db, p, true);
  49.     vector<int> res;
  50.     for (size_t u = 0; u < g.size(); u++)
  51.     {
  52.         if (da[u] + db[u] == da[b])
  53.             res.push_back(u);
  54.     }
  55.     return res;
  56. }
  57.  
  58. //https://pastebin.com/6MDNTGUj
  59.  
  60. struct cell { int r, c; };
  61. const cell nullcell = cell{ -1,-1 };
  62.  
  63. template <typename T>
  64. class table
  65. {
  66. public:
  67.     vector<vector<T>> m;
  68.     table(size_t _rows = 0, size_t _cols = 0, T val = T()) { m.assign(_rows, vector<T>(_cols, val)); }
  69.     size_t rows()const { return m.size(); }
  70.     size_t cols()const { return m.size() ? m[0].size() : 0; }
  71.     T operator[](cell c)const { return m[c.r][c.c]; }
  72.     T& operator[](cell c) { return m[c.r][c.c]; }
  73. };
  74.  
  75. using labyrinth = table<char>;
  76.  
  77. labyrinth get_labyrinth_from_stream(std::istream& inp)
  78. {
  79.     int row, col;
  80.     inp >> row >> col;
  81.     labyrinth lab(row, col);
  82.     for (int i = 0; i < row; i++)
  83.     {
  84.         for (int j = 0; j < col; j++)
  85.         {
  86.             char c;
  87.             inp >> c;
  88.             lab[{row - i - 1, j}] = c;
  89.         }
  90.     }
  91.     return lab;
  92. }
  93.  
  94. vector<cell> adjoint_cells(const labyrinth& lab, cell c)
  95. {
  96.     vector<cell> res;
  97.     for (int i = -1; i <= 1; ++i)
  98.     {
  99.         if (i != 0 && i + c.r >= 0 && i + c.r < lab.rows())
  100.             res.push_back({ i + c.r,c.c });
  101.         if (i != 0 && i + c.c >= 0 && i + c.c < lab.cols())
  102.             res.push_back({ c.r,i + c.c });
  103.     }
  104.     return res;
  105. }
  106.  
  107. void BFSlab(const labyrinth& lab, const vector<cell>& s, table<int>& d, table<cell>& p,
  108.     std::function<vector<cell>(const labyrinth&,cell)> adj_cells = adjoint_cells)
  109. {
  110.     int infty = lab.rows() * lab.cols();
  111.     d = table<int>(lab.rows(), lab.cols(), infty);
  112.     p = table<cell>(lab.rows(), lab.cols(), nullcell);
  113.     std::queue<cell> Q;
  114.     for (auto c : s)
  115.     {
  116.         d[c] = 0;
  117.         Q.push(c);
  118.     }
  119.     while (Q.size())
  120.     {
  121.         auto c = Q.front();
  122.         Q.pop();
  123.         for (auto v : adj_cells(lab, c))
  124.         {
  125.             if ((lab[v]) != '#' && (d[v]) == infty)
  126.             {
  127.                 d[v] = d[c] + 1;
  128.                 p[v] = c;
  129.                 Q.push(v);
  130.             }
  131.         }
  132.     }
  133. }
  134.  
  135. void BFSlab_fire(const labyrinth& lab, cell s, double fire_speed, table<int>& d, table<cell>& p)
  136. {
  137.     int infty = lab.rows() * lab.cols();
  138.     d = table<int>(lab.rows(), lab.cols(), infty);
  139.     p = table<cell>(lab.rows(), lab.cols(), nullcell);
  140.  
  141.     table<int> dfire;
  142.     table<cell> pfire;
  143.     vector<cell> firecells;
  144.     for (int i = 0; i < lab.rows(); ++i)
  145.         for (int j = 0; j < lab.cols(); j++)
  146.             if (lab[{i, j}] == 'F') firecells.push_back({ i, j });
  147.     BFSlab(lab, firecells, dfire, pfire);
  148.  
  149.     d[s] = 0;
  150.     std::queue<cell> Q;
  151.     Q.push(s);
  152.     while (Q.size())
  153.     {
  154.         auto c = Q.front();
  155.         Q.pop();
  156.         for (auto v : adjoint_cells(lab, c))
  157.         {
  158.             if (lab[v] != '#' && d[v] == infty && d[c] < fire_speed * dfire[v])
  159.             {
  160.                 d[v] = d[c] + 1;
  161.                 p[v] = c;
  162.                 Q.push(v);
  163.             }
  164.         }
  165.     }
  166. }
  167.  
  168. vector<cell> adjoint_cells_for_slime(const labyrinth& lab, cell c)
  169. {
  170.     if (c.r > 0 && lab[{c.r - 1, c.c}] != '#')
  171.         return { {c.r - 1, c.c} };
  172.     vector<cell> res;
  173.     if (c.c > 0) res.push_back({ c.r,c.c - 1 });
  174.     if (c.c < lab.cols()-1) res.push_back({ c.r,c.c + 1 });
  175.     return res;
  176. }
  177.  
  178. void BFSlab_slime(const labyrinth& lab, cell s, double slime_speed, double slime_slowdown, table<int>& d, table<cell>& p)
  179. {
  180.     int infty = lab.rows() * lab.cols()*std::max(1.0,slime_slowdown);
  181.     d = table<int>(lab.rows(), lab.cols(), infty);
  182.     p = table<cell>(lab.rows(), lab.cols(), nullcell);
  183.  
  184.     table<int> dslime;
  185.     table<cell> pslime;
  186.     vector<cell> slimecells;
  187.     for (int i = 0; i < lab.rows(); ++i)
  188.         for (int j = 0; j < lab.cols(); j++)
  189.             if (lab[{i, j}] == 'S') slimecells.push_back({ i, j });
  190.     BFSlab(lab, slimecells, dslime, pslime,adjoint_cells_for_slime);
  191.  
  192.     d[s] = 0;
  193.     std::queue<cell> Q;
  194.     Q.push(s);
  195.     while (Q.size())
  196.     {
  197.         auto c = Q.front();
  198.         Q.pop();
  199.         for (auto v : adjoint_cells(lab, c))
  200.         {
  201.             double time_for_step = d[c]>=dslime[c]*slime_speed ? slime_slowdown : 1.0;
  202.             if (lab[v] == '#') continue;
  203.             if (d[v] == infty || d[v] > d[c]+time_for_step)
  204.             {
  205.                 d[v] = d[c] + time_for_step;
  206.                 p[v] = c;
  207.                 Q.push(v);
  208.             }
  209.         }
  210.     }
  211. }
  212.  
  213. void BFSlab_dynamite(const labyrinth& lab, const vector<cell>& s, int D,
  214.     table<vector<int>>& d, table<vector<std::pair<cell,int>>>& p,
  215.     std::function<vector<cell>(const labyrinth&, cell)> adj_cells = adjoint_cells)
  216. {
  217.     int infty = lab.rows() * lab.cols();
  218.     d = table<vector<int>>(lab.rows(), lab.cols(), vector<int>(D+1,infty));
  219.     p = table<vector<std::pair<cell, int>>>(lab.rows(), lab.cols(),
  220.         vector<std::pair<cell, int>>(D + 1, { nullcell,0 }));
  221.     std::queue<std::pair<cell,int>> Q;
  222.     for (auto c : s)
  223.     {
  224.         d[c][D] = 0;
  225.         Q.push({ c,D });
  226.     }
  227.     while (Q.size())
  228.     {
  229.         auto [c,r] = Q.front();
  230.         Q.pop();
  231.         for (auto v : adj_cells(lab, c))
  232.         {
  233.             if (lab[v] == '#' && r > 0 && d[v][r - 1] > d[c][r] + 1)
  234.             {
  235.                 d[v][r - 1] = d[c][r] + 1;
  236.                 Q.push({ v,r - 1 });
  237.                 p[v][r - 1] = { c,r };
  238.             }
  239.             else if ((lab[v]) != '#' && d[v][r] > d[c][r] + 1)
  240.             {
  241.                 d[v][r] = d[c][r] + 1;
  242.                 p[v][r] = { c,r };
  243.                 Q.push({ v,r });
  244.             }
  245.         }
  246.     }
  247. }
  248.  
  249.  
  250. int main()
  251. {
  252.     std::ifstream inp("lab.txt");
  253.     auto lab = get_labyrinth_from_stream(inp);
  254.     //table<int> d;
  255.     //table<cell> p;
  256.     //BFSlab(lab, { { 0,0 } }, d, p);
  257.     //BFSlab_fire(lab, { 0,0 }, 1.8, d, p);
  258.     //BFSlab_slime(lab, { 0,0 }, 2.0, 5.0, d, p);
  259.     //std::cout << (d[{ 11, 11 }]) << std::endl;
  260.     //cell current = { 11,11 };
  261.     //while (current.r != -1)
  262.     //{
  263.     //    std::cout << current.r << ',' << current.c << "  ";
  264.     //    current = p[current];
  265.     //}
  266.     //std::wcout << std::endl;
  267.     table<vector<int>> d;
  268.     table<vector<std::pair<cell, int>>> p;
  269.     BFSlab_dynamite(lab, { {0,0} }, 1, d, p);
  270.     std::cout << d[{ 11, 11 }][1] << std::endl;
  271.     cell current = { 11,11 };
  272.     int dynamite = 1;
  273.     while (current.r != -1)
  274.     {
  275.         std::cout << current.r << ',' << current.c << "("<<dynamite<<")  ";
  276.         auto cd = p[current][dynamite];
  277.         current = cd.first;
  278.         dynamite = cd.second;
  279.     }
  280.     std::wcout << std::endl;
  281. }
  282.  
  283. // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
  284. // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
  285.  
  286. // Советы по началу работы
  287. //   1. В окне обозревателя решений можно добавлять файлы и управлять ими.
  288. //   2. В окне Team Explorer можно подключиться к системе управления версиями.
  289. //   3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
  290. //   4. В окне "Список ошибок" можно просматривать ошибки.
  291. //   5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
  292. //   6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
  293. /*
  294.  
  295. https://pastebin.com/z1sehyKw
  296.  
  297. 12 12
  298. ...#..#.....
  299. ........###.
  300. .###.##.#.##
  301. ...###..#...
  302. ...#.#.##.#.
  303. #.##.#....#F
  304. ..#..#..###.
  305. .##........F
  306. ..#..######.
  307. #........F#.
  308. #.#####.##..
  309. ......#...#.
  310. */
Advertisement
Add Comment
Please, Sign In to add comment