-
백준 16957번 체스판 위의 공PS 2020. 3. 24. 12:55
https://www.acmicpc.net/problem/16957
16957번: 체스판 위의 공
크기가 R×C인 체스판이 있고, 체스판의 각 칸에는 정수가 하나씩 적혀있다. 체스판에 적혀있는 정수는 모두 서로 다르다. 체스판의 각 칸 위에 공을 하나씩 놓는다. 이제 공은 다음과 같은 규칙에 의해서 자동으로 움직인다. 인접한 8방향 (가로, 세로, 대각선)에 적힌 모든 정수가 현재 칸에 적힌 수보다 크면 이동을 멈춘다. 그 외의 경우에는 가장 작은 정수가 있는 칸으로 공이 이동한다. 공의 크기는 매우 작아서, 체스판의 한 칸 위에 여러 개의 공이 있을
www.acmicpc.net
<접근방법>
접근 방법이 다양한 문제입니다.
저는 그냥 bfs, 우선순위 큐를 활용한 bfs, dp로 풀었습니다.
공은 큰 곳에서 작은 곳으로 흐르기 때문에 우선순위 큐를 활용해 풀 수 있습니다.
1 - 2 - 3 - 4
2 - 3 - 4
1 -> 4인 공괴 2 -> 4 인 공은 경로가 겹칩니다.
이 경로를 저장해놓고 중복 탐색을 방지하는 dp로 문제를 풀 수 있습니다.
<느낀 점>
중복탐색 - dp
<코드>
#include <iostream> #include <algorithm> #include <queue> using namespace std; struct point { int val, y, x; }; int n, m; int map[500][500], visit[500][500]; int dy[8] = { 1, -1, 0, 0, 1, 1, -1, -1 }; int dx[8] = { 0, 0, 1, -1, 1, -1, 1, -1 }; struct cmp { bool operator()(point a, point b) { return a.val < b.val; } }; priority_queue<point, vector<point>, cmp> q; void bfs() { while (!q.empty()) { point t = q.top(); q.pop(); if (visit[t.y][t.x] == 0) continue; int tmp = 987654321; int my, mx; for (int i = 0; i < 8; i++) { int ny = t.y + dy[i]; int nx = t.x + dx[i]; if (ny < 0 || ny >= n || nx < 0 || nx >= m) continue; if (tmp > map[ny][nx]) { tmp = map[ny][nx]; my = ny; mx = nx; } } if (tmp <= map[t.y][t.x]) { visit[my][mx] += visit[t.y][t.x]; visit[t.y][t.x] = 0; q.push({map[my][mx], my, mx }); } } } int main() { cin >> n >> m; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> map[i][j]; q.push({map[i][j], i, j }); visit[i][j]++; } } bfs(); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cout << visit[i][j] << ' '; } puts(""); } return 0; }
#include <iostream> #include <algorithm> #include <memory.h> using namespace std; struct point { int y, x; }; int n, m; int map[501][501], ans[501][501]; bool visit[501][501]; point cache[501][501]; int dy[8] = { 1, -1, 0, 0, 1, 1, -1, -1 }; int dx[8] = { 0, 0, 1, -1, 1, -1, 1, -1 }; point dfs(int y, int x) { point &res = cache[y][x]; bool &visited = visit[y][x]; if (visited) return res; visited = true; //res.y = y; res.x = x; res = {y, x}; int now_val = map[y][x]; int ty, tx; for (int i = 0; i < 8; i++) { int ny = y + dy[i]; int nx = x + dx[i]; if (ny < 0 || ny >= n || nx < 0 || nx >= m) continue; if (now_val > map[ny][nx]) { now_val = map[ny][nx]; ty = ny; tx = nx; } } if (now_val != map[y][x]) return res = dfs(ty, tx); return res; } int main() { cin >> n >> m; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> map[i][j]; } } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { point t = dfs(i, j); ans[t.y][t.x]++; } } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cout << ans[i][j] << ' '; } puts(""); } return 0; }
반응형'PS' 카테고리의 다른 글
백준 16973번 직사각형 탈출 (0) 2020.04.08 백준 16940번 BFS 스페셜 저지 (0) 2020.04.08 백준 5014번 스타트링크 (0) 2020.03.24 백준 17069번 파이프 옮기기2 (0) 2020.03.22 백준 16931번 겉넓이 구하기 (0) 2020.03.21