Skip to content

Commit

Permalink
Merge pull request #47 from HYU-PS-STUDY/wonkyDD
Browse files Browse the repository at this point in the history
[week-08] 13460, 17143
  • Loading branch information
wonkyDD authored Mar 19, 2024
2 parents ec1aee8 + fde631a commit 977363a
Show file tree
Hide file tree
Showing 3 changed files with 298 additions and 0 deletions.
Empty file removed week08/wonkyDD/.gitkeep
Empty file.
123 changes: 123 additions & 0 deletions week08/wonkyDD/13460.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#include <iostream>
#include <queue>
#include <vector>
#include <climits>
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<N; ++i) {
for (int j=0; j<M; ++j) {
cin >> 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;
}
175 changes: 175 additions & 0 deletions week08/wonkyDD/17143.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define MAX 101
struct shark {
int id;
int y; int x;
int speed;
int dir;
int size;
bool is_dead;
};
// NOTE : <dummy>, UP, DOWN, RIGHT, LEFT
int dy[] = {-9, -1, 1, 0, 0};
int dx[] = {-9, 0, 0, 1, -1};

int R,C,M;
vector<shark> sharks;
vector<int> 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<speed; ++i) {
// NOTE : 일단 갱신을 하고, 위치 보정을 한다
ny += dy[dir]; nx += dx[dir];
if (ny < 1) {
ny += 2;
dir = inverse_dir(dir);
}
else if (ny > 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<speed; ++i) {
// NOTE : 일단 갱신을 하고, 위치 보정을 한다
ny += dy[dir]; nx += dx[dir];
if (nx < 1) {
nx += 2;
dir = inverse_dir(dir);
}
else if (nx > 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<map[i][j].size(); ++k) {
int shark_id = map[i][j][k];
sharks[shark_id].is_dead = true;
}

// NOTE : 모두 비워주고 가장 size가 큰 상어만 남긴다
map[i][j].clear();
map[i][j].push_back(max_size_shark_id);
}
}
}
}

int main() {
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);

cin >> R >> C >> M;
int r,c,speed,dir,size;
for (int i=0; i<M; ++i) {
cin >> 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;
}

0 comments on commit 977363a

Please sign in to comment.