diff --git a/week08/wonkyDD/.gitkeep b/week08/wonkyDD/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/week08/wonkyDD/13460.cpp b/week08/wonkyDD/13460.cpp new file mode 100644 index 0000000..cbbdcf3 --- /dev/null +++ b/week08/wonkyDD/13460.cpp @@ -0,0 +1,123 @@ +#include +#include +#include +#include +using namespace std; + +#define MAX 10 +struct pos { + int y; int x; +}; +int dy[] = {-1, 1, 0, 0}; +int dx[] = {0, 0, -1, 1}; + +int N, M; +char board[MAX][MAX]; +int ans = INT_MAX; + +int count(int cy, int ncy, int cx, int ncx) { + return abs(cy-ncy) + abs(cx-ncx); +} + +int inverse(int dir) { + int inv; + switch (dir) + { + case 0: + inv = 1; + break; + case 1: + inv = 0; + break; + case 2: + inv = 3; + break; + case 3: + inv = 2; + break; + } + return inv; +} + +void dfs(pos red, pos blue, int cnt, int dir) { + if (cnt > 10 || cnt >= ans) return; + + // NOTE : 빨간 구슬이 탈출하는지 확인한다 + int nry = red.y, nrx = red.x; + bool red_out = false; + while (1) { + nry += dy[dir]; nrx += dx[dir]; + if (board[nry][nrx] == '#') break; + if (board[nry][nrx] == 'O') { + red_out = true; + break; + } + } + // NOTE : # or O => . 위치로 한칸 보정 + nry -= dy[dir]; nrx -= dx[dir]; + + // NOTE : 파란 구슬이 탈출하는지 확인한다 + int nby = blue.y, nbx = blue.x; + while (1) { + nby += dy[dir]; nbx += dx[dir]; + if (board[nby][nbx] == '#') break; + // NOTE : 파란 구슬이 탈출 했다면 바로 탐색을 종료한다 + if (board[nby][nbx] == 'O') { + return; + } + } + // NOTE : # or O => . 위치로 한칸 보정 + nby -= dy[dir]; nbx -= dx[dir]; + + // NOTE : 빨간 구슬이 탈출했다면 ans를 갱신한다 + if (red_out) { + ans = min(ans, cnt); + return; + } + + /** + * NOTE + * - 빨간 / 파란 구슬은 같은 칸에 존재할 수 없다 + * - 하지만 빨/파 구슬에 대해 각각 while을 돌리고 있으므로 값이 같아지는 상황이 나오게 된다 + * - 따라서 값이 같았을 경우 이동한 거리가 큰 쪽을 한칸 보정해준다 + */ + if ((nry == nby) && (nrx == nbx)) { + int rd = count(red.y, nry, red.x, nrx); + int bd = count(blue.y, nby, blue.x, nbx); + + // NOTE : 기울였을 때 더 많이 움직였다면 한칸 되돌려 줘야 한다 + if (rd > bd) { nry -= dy[dir]; nrx -= dx[dir]; } + else { nby -= dy[dir]; nbx -= dx[dir]; } + } + + for (int i=0; i<4; ++i) { + // NOTE : 이전 뱡향과 똑같은 방향 or 반대방향 (되돌아가는) 은 의미가 없다 + if (i == dir || i == inverse(dir)) continue; + + pos nr = {nry, nrx}, nb = {nby, nbx}; + dfs(nr, nb, cnt+1, i); + } +} + +int main() { + ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr); + + cin >> N >> M; + pos r,b; + + for (int i=0; i> board[i][j]; + if (board[i][j] == 'R') r = {i, j}; + else if (board[i][j] == 'B') b = {i, j}; + } + } + + for (int i=0; i<4; ++i) { + dfs(r, b, 1, i); + } + + if (ans == INT_MAX || ans > 10) ans = -1; + cout << ans; + return 0; +} \ No newline at end of file diff --git a/week08/wonkyDD/17143.cpp b/week08/wonkyDD/17143.cpp new file mode 100644 index 0000000..fec71ee --- /dev/null +++ b/week08/wonkyDD/17143.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +using namespace std; + +#define MAX 101 +struct shark { + int id; + int y; int x; + int speed; + int dir; + int size; + bool is_dead; +}; +// NOTE : , UP, DOWN, RIGHT, LEFT +int dy[] = {-9, -1, 1, 0, 0}; +int dx[] = {-9, 0, 0, 1, -1}; + +int R,C,M; +vector sharks; +vector map[MAX][MAX]; +int fisher = 1; +int ans = 0; + +bool is_over() { + for (const auto& shark : sharks) { + if (!shark.is_dead) return false; + } + return true; +} + +void fish() { + // NOTE : 낚시꾼은 지면과 가장 가까운 곳부터 낚시를 시작한다 + for (int i=1; i<=R; ++i) { + // NOTE : shark id가 담겨있는 위치를 찾는다 + if (!map[i][fisher].empty()) { + int shark_id = map[i][fisher][0]; + ans += sharks[shark_id].size; + + // NOTE : 포획했기 때문에 죽었다고 표기하고 해당 위치의 map은 비워준다 + sharks[shark_id].is_dead = true; + map[i][fisher].clear(); + break; + } + } +} + +int inverse_dir(int dir) { + if (dir == 1) return 2; + else if (dir == 2) return 1; + else if (dir == 3) return 4; + else return 3; +} + +void move() { + for (const auto& shark : sharks) { + // NOTE : 포획된 상어는 고려하지 않는다 + if (shark.is_dead) continue; + + int y = shark.y, x = shark.x; + + // NOTE : 이제 이동할 것이기 때문에 기존 위치의 shark id 컨테이너는 비워준다 + map[y][x].clear(); + } + + for (auto& shark : sharks) { + // NOTE : 죽은 상어는 이동시키지 않는다 + if (shark.is_dead) continue; + + int y = shark.y, x = shark.x, dir = shark.dir, speed = shark.speed; + int ny = y, nx = x; + + // NOTE : 이동 방향이 UP or DOWN + if (dir == 1 || dir == 2) { + /** + * NOTE + * - 이동 방향이 위아래니까 R이 기준이다 + * - 기존 방향을 유지하며, 원래의 위치로 돌아오는데 걸리는 주기는 2 * (R-1)이다 + */ + int period = 2 * (R-1); + if (speed >= period) speed %= period; + + for (int i=0; i R) { + ny -= 2; + dir = inverse_dir(dir); + } + } + } + // NOTE : 이동 방향이 RIGHT or LEFT + else { + /** + * NOTE + * - 이동 방향이 위아래니까 C가 기준이다 + * - 기존 방향을 유지하며, 원래의 위치로 돌아오는데 걸리는 주기는 2 * (C-1)이다 + */ + int period = 2 * (C-1); + if (speed >= period) speed %= period; + + for (int i=0; i C) { + nx -= 2; + dir = inverse_dir(dir); + } + } + } + + // NOTE : 새롭게 갱신한 좌표 자리에 shark id를 넣어준다 + shark.y = ny; + shark.x = nx; + shark.dir = dir; + map[ny][nx].push_back(shark.id); + } +} + +// NOTE : size 기준으로 shark id를 내림 차순 정렬한다 +bool cmp(int a, int b) { + return sharks[a].size > sharks[b].size; +} + +void eat() { + for (int i=1; i<=R; ++i) { + for (int j=1; j<=C; ++j) { + if (map[i][j].size() > 1) { + sort(map[i][j].begin(), map[i][j].end(), cmp); + + // NOTE : 가장 size가 큰 shark의 id + int max_size_shark_id = map[i][j][0]; + + // NOTE : 다른 상어들은 가장 큰 상어에게 모두 잡아먹힌다 (is_dead = true) + for (int k=1; k> R >> C >> M; + int r,c,speed,dir,size; + for (int i=0; i> r >> c >> speed >> dir >> size; + sharks.push_back({i, r, c, speed, dir, size, false}); + map[r][c].push_back(i); + } + + for (; fisher<=C; ++fisher) { + if (is_over()) break; + fish(); + move(); + eat(); + } + cout << ans; + return 0; +} \ No newline at end of file