728x90
반응형
https://www.acmicpc.net/problem/16137
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#include<stdio.h>
#include<queue>
#include<string.h>
#define NSIZE 10
#define MSIZE 20
using namespace std;
int N, M;
int input[NSIZE][NSIZE];
int chk[NSIZE][NSIZE];
int dy[] = { 0,1,0,-1 };
int dx[] = { 1,0,-1,0 };
int ret = 0;
int Min = 0x7fffffff;
struct Data {
int y, x, cnt, time;
};
void init() {
scanf("%d %d", &N, &M);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
scanf("%d", &input[i][j]);
}
}
}
bool chkHole(int y,int x) {
int cnt = 0;
for (int dir = 0; dir < 4; dir++) {
int ny = y+dy[dir]; int nx = x+dx[dir];
int nny = y+dy[(dir+1)%4]; int nnx = x+dx[(dir + 1) % 4];
if (0 <= ny && ny < N && 0 <= nx && nx < N&& 0 <= nny && nny < N && 0 <= nnx && nnx < N) {
if (input[ny][nx] == 0 && input[nny][nnx] == 0) return false;
}
}
return true;
}
void bfs() {
queue<Data>q;
memset(chk, 0x32, sizeof(chk));
q.push({ 0,0,0,0 });
chk[0][0] = 1;
while (!q.empty()) {
Data c = q.front(); q.pop();
if (c.y == N - 1 && c.x == N - 1) {
ret = chk[c.y][c.x];
return;
}
for (int dir = 0; dir < 4; dir++) {
Data n;
n.y = c.y + dy[dir];
n.x = c.x + dx[dir];
n.cnt = c.cnt+1;
n.time = c.time;
if (0 <= n.y && n.y < N && 0 <= n.x && n.x < N) {
if (chk[n.y][n.x]>=n.cnt && input[n.y][n.x] >= 1) {
if (input[n.y][n.x] >= 2&&n.time==0) {
if ( n.cnt%input[n.y][n.x] == 0) {
chk[n.y][n.x] = n.cnt;
n.time = 1;
q.push(n);
}
else {
n.cnt = n.cnt + (input[n.y][n.x]-(n.cnt % input[n.y][n.x]));
chk[n.y][n.x] = n.cnt;
n.time = 1;
q.push(n);
}
}
else if(input[n.y][n.x]==1) {
if (n.time == 1)n.time = 0;
chk[n.y][n.x] = n.cnt;
q.push(n);
}
}
}
}
}
}
void meeting() {
ret = 0x7fffffff;
bfs();
if (Min > ret)Min = ret;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (input[i][j] == 0 && chkHole(i, j)) {
input[i][j] = M;
ret = 0x7fffffff;
bfs();
if (Min > ret)Min = ret;
input[i][j] = 0;
}
}
}
}
int main(void) {
init();
meeting();
printf("%d\n", Min);
return 0;
}
|
1번 견우와 직녀 알고리즘 포인트는 우선 최소로 거리가 가도록 해야하기때문에 약간 다엑스트라 방식을 적용해야하고
2번 오작교는 1초되면 사라지기때문에 두번 연속 못 건너가게하는 변수 하나 더 선언하고
3 번오작교에 도달했을때 오작교생성 시간 계산해서 큐에 넣어주기만 하면 됩니다.
사실 1 번 2 번 방식은 진짜 쉽다고 생각할 수 있습니다. 1번은 그냥 체크배열을 가장 큰값으로 초기화하고
간시간보다 작으면 다시 그거리를 큐에 넣으면 되기 때문에 쉽게 구현 가능하고
2번은 변수에 오작교를 일단 갔으면 1로 체크를 해주고 그렇지 않으면 오작교를 건너는 식으로 구현하면됩니다.
이걸 보면 n.time 이라는 변수에 1로 오작교 건넜음을 체크해주면됩니다.
하지만 다시 오작교가 아닌 거리에 오면 0으로 만들어줘야함을 잊지마세요.
이제 마지막으로 3번은
소스를 보시면
이건데 왜 저렇게 되냐 말씀드리면 이렇습니다.
이해가 안되실 수 있는데 이해가 되셨으면 좋겠습니다. 저렇게 하면 답이 통과가 되더라구요
오늘도 여기까지이고 즐거운 코딩하세요.
728x90
반응형
'알고리즘 모음집 > 알고리즘 (Algorithm)' 카테고리의 다른 글
백준 2065 나룻배 (0) | 2019.10.02 |
---|---|
백준 2931 가스관 (0) | 2019.10.02 |
백준 4577 소코반 (0) | 2019.09.30 |
백준 1260 DFS와 BFS (0) | 2019.09.29 |
백준 15662 톱니바퀴(2) (0) | 2019.09.29 |
댓글