Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <iostream>
- #include <vector>
- #include <cassert>
- #define N 55
- #define pb push_back
- #define INF int(1e9)
- using namespace std;
- char type[30];
- int lab[N][N];
- struct two
- {
- int x, y;
- two() {}
- two(int a, int b)
- {
- x = a, y = b;
- }
- };
- two hole[N][N];
- int x_hole[N * N], y_hole[N * N];
- bool wall[N][N][4];
- vector<int> w[N][N];
- vector<two> graph[N][N];
- two from[N][N];
- int dist[N][N];
- bool used[N][N], out[N][N], ref[N][N];
- void answer(int x, int y)
- {
- if (from[x][y].x)
- answer(from[x][y].x, from[x][y].y);
- if (from[x][y].x != x || from[x][y].y != y) printf("%d %d\n",x, y);
- }
- int main()
- {
- freopen("princess.in", "r", stdin);
- freopen("princess.out", "w", stdout);
- int n, m, k;
- scanf("%d %d %d ", &m, &n, &k);
- for (int i = 0; i < k; i++)
- {
- int x, y;
- scanf("%d %d %*c ", &x, &y);
- out[x][y] = true;
- }
- int z;
- scanf("%d ", &z);
- for (int i = 0; i < z; i++)
- {
- int x, y;
- scanf("%d %d %s", &x, &y, type);
- switch (type[0])
- {
- case 'P': lab[x][y] += 2; break;
- case 'M': lab[x][y] += 4; break;
- case 'A': lab[x][y] += 6; break;
- case 'B':
- {
- if (type[1] == 'A')
- lab[x][y] += 8;
- else
- lab[x][y] += 10;
- break;
- }
- }
- }
- int W;
- scanf("%d ", &W);
- for (int i = 0; i < W; i++)
- {
- int x, y;
- char side;
- scanf("%d %d %c ", &x, &y, &side);
- switch (side)
- {
- case 'L': wall[x][y][0] = wall[x - 1][y][1] = true; break;
- case 'R': wall[x][y][1] = wall[x + 1][y][0] = true; break;
- case 'U': wall[x][y][2] = wall[x][y - 1][3] = true; break;
- case 'D': wall[x][y][3] = wall[x][y + 1][2] = true; break;
- }
- }
- int l;
- scanf("%d ", &l);
- for (int i = 0; i < l; i++)
- {
- int p;
- scanf("%d ", &p);
- /*if (p == 1)
- {
- int x, y;
- scanf("%d %d ", &x, &y);
- ref[x][y] = true;
- continue;
- }*/
- for (int j = 0; j < p; j++)
- {
- scanf("%d %d ", x_hole + j, y_hole + j);
- if (j)
- hole[ x_hole[j-1] ][ y_hole[j-1] ] = two( x_hole[j], y_hole[j] );
- if (j == p - 1)
- hole[ x_hole[j] ][ y_hole[j] ] = two( x_hole[0], y_hole[0] );
- }
- }
- for (int i = 1; i <= m; i++)
- for (int j = 1; j <= n; j++)
- {
- if (hole[i][j].x)
- {
- graph[i][j].pb( hole[i][j] );
- // printf("(%d, %d) -> (%d, %d)\n", i, j, hole[i][j].x, hole[i][j].y);
- w[i][j].pb(0);
- }
- if (!wall[i][j][0] && i - 1) // to the left
- {
- if (hole[i - 1][j].x)
- {
- graph[i][j].pb( hole[i - 1][j] );
- // printf("(%d, %d) -> (%d, %d)\n", i, j, hole[i - 1][j].x, hole[i - 1][j].y);
- w[i][j].pb(0);
- }
- else
- {
- graph[i][j].pb( two(i - 1, j) );
- // printf("(%d, %d) -> (%d, %d)\n", i, j, i - 1, j);
- w[i][j].pb(lab[i - 1][j]);
- }
- }
- if (!wall[i][j][1] && i + 1 <= m) // to the right
- {
- if (hole[i + 1][j].x)
- {
- graph[i][j].pb( hole[i + 1][j] );
- // printf("(%d, %d) -> (%d, %d)\n", i, j, hole[i + 1][j].x, hole[i + 1][j].y);
- w[i][j].pb(0);
- }
- else
- {
- graph[i][j].pb( two(i + 1, j) );
- // printf("(%d, %d) -> (%d, %d)\n", i, j, i + 1, j);
- w[i][j].pb(lab[i + 1][j]);
- }
- }
- if (!wall[i][j][2] && j - 1) // up
- {
- if (hole[i][j - 1].x)
- {
- graph[i][j].pb( hole[i][j - 1] );
- // printf("(%d, %d) -> (%d, %d)\n", i, j, hole[i][j - 1].x, hole[i][j - 1].y);
- w[i][j].pb(0);
- }
- else
- {
- graph[i][j].pb( two(i, j - 1) );
- // printf("(%d, %d) -> (%d, %d)\n", i, j, i, j - 1);
- w[i][j].pb(lab[i][j - 1]);
- }
- }
- if (!wall[i][j][3] && j + 1 <= n) // down
- {
- if (hole[i][j + 1].x)
- {
- graph[i][j].pb( hole[i][j + 1] );
- // printf("(%d, %d) -> (%d, %d)\n", i, j, hole[i][j + 1].x, hole[i][j + 1].y);
- w[i][j].pb(0);
- }
- else
- {
- graph[i][j].pb( two(i, j + 1) );
- // printf("(%d, %d) -> (%d, %d)\n", i, j, i, j + 1);
- w[i][j].pb(lab[i][j + 1]);
- }
- }
- }
- int x_start, y_start;
- scanf("%d %d %*d %*d ", &x_start, &y_start);
- for (int i = 0; i < N; i++)
- for (int j = 0; j < N; j++)
- dist[i][j] = INF;
- dist[x_start][y_start] = lab[x_start][y_start];
- for (int iter = 0; iter < n * m; iter++)
- {
- int ind_x = 0, ind_y = 0, val = INF + 1;
- for (int x = 1; x <= m; x++)
- for (int y = 1; y <= n; y++)
- {
- if (!used[x][y] && dist[x][y] < val)
- {
- val = dist[x][y];
- ind_x = x, ind_y = y;
- }
- }
- used[ind_x][ind_y] = true;
- for (int i = 0; i < graph[ind_x][ind_y].size(); i++)
- {
- two u = graph[ind_x][ind_y][i];
- if ( dist[u.x][u.y] > dist[ind_x][ind_y] + w[ind_x][ind_y][i])
- {
- dist[u.x][u.y] = dist[ind_x][ind_y] + w[ind_x][ind_y][i];
- from[u.x][u.y] = two(ind_x, ind_y);
- }
- }
- }
- int res = INF, x_finish, y_finish;
- for (int x = 1; x <= m; x++)
- for (int y = 1; y <= n; y++)
- if (out[x][y] && !ref[x][y])
- {
- if (dist[x][y] < res)
- {
- res = dist[x][y];
- x_finish = x;
- y_finish = y;
- }
- }
- if (res == INF)
- {
- cout << -1;
- return 0;
- }
- printf("%d\n", res);
- answer(x_finish, y_finish);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement