[SWEA] 2382. [모의 SW 역량테스트] 미생물 격리★

Apr 2, 2019


https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV597vbqAH0DFAVl&

약친 곳이나 미생물의 이동은 코드를 참고하시면 되겠습니다.

미생물 격리에서 유의할 점은 서로 겹칠 때를 판단하는 것 입니다.

저는 두가지 방법으로 문제를 풀었습니다.

1.sort를 하여 우선순위를 정한 후 판단 배열을 미생물의 수를 기준으로 내림차순하면

따로 겹칠때 계산할 게 없습니다. 그냥 먼저 자리를 차지한 녀석에게 미생물의 수를 더하고

뒤에 온녀석은 없애면 그만입니다. 단점은 sort를 매 시간마다 해줘야하므로 시간이 좀 필요합니다 (565ms)

2.map배열을 3차원으로 하여 판단 map[x][y][0]은 미생물의 번호, map[x][y][1]은 미생물의 수로 한 후

겹칠때마다 서로 비교하여 넣어 줍니다. 이렇게 하면 시간은 좀 단축하여 풀 수 있습니다. (303ms)

단점은 머리를 좀 굴려야해서 실수가 발생할 수 있다는 점…ㅎㅎ;;

1.sort를 하여 우선순위를 정한 후 판단

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int n, m, k;
int map[101][101];//이동 후 자리
struct Info {
    int x;
    int y;
    int num;
    int dir;
}micro[1001];
bool comp(Info a, Info b) {//미생물의 수를 오름차순 정렬
    return a.num > b.num;
}
int dx[] = { 0,-1,1,0,0 };
int dy[] = { 0,0,0,-1,1 };
queue <pair<int, int>> q;//map의 빠른 초기화를 위해 큐사용
void move() {
    while (m--) {
        for (int i = 0; i < k; i++) {
            if (micro[i].num == 0) break;//0이면 뒤에도 다 0이므로 break
            int x = micro[i].x;
            int y = micro[i].y;
            int num = micro[i].num;
            int dir = micro[i].dir;
            int nx = x + dx[dir];
            int ny = y + dy[dir];
            //약친곳
            if (nx == 0 || ny == 0 || nx == n - 1 || ny == n - 1) {
                num /= 2;
                if (dir == 1 || dir == 3) dir += 1;
                else dir -= 1;
                micro[i].dir = dir;
                micro[i].num = num;
            }
            //이동
            if (map[nx][ny] == -1) {
                map[nx][ny] = i;
                q.push(make_pair(nx, ny));
            }
            else {//겹치는곳
                micro[map[nx][ny]].num += num;
                micro[i].num = 0;
                continue;
            }
            micro[i].x = nx;
            micro[i].y = ny;
        }
        sort(micro, micro + k, comp);//다시 정렬
        while (!q.empty()) {//초기화
            map[q.front().first][q.front().second] = -1;
            q.pop();
        }
    }
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int test_case;
    cin >> test_case;
    for (int t = 1; t <= test_case; t++) {
        //start
        cin >> n >> m >> k;
        for (int i = 0; i < 101; i++)
            for (int j = 0; j < 101; j++)
                map[i][j] = -1;//map -1로 초기화
        for (int i = 0; i < k; i++)
            cin >> micro[i].x >> micro[i].y >> micro[i].num >> micro[i].dir;
        sort(micro, micro + k, comp);//정렬
        move();
        //end
        int result = 0;
        for (int i = 0; i < k; i++) {
            if (micro[i].num > 0) result += micro[i].num;
            else break;
        }
        cout << '#' << t << ' ' << result << '\n';
    }
}

2.map배열을 3차원으로 하여 판단

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
//13:33
int n, m, k;
int map[101][101][2];//map[x][y][0]은 미생물의번호, [1]은 미생물 수
struct Info {
    int x;
    int y;
    int num;
    int dir;
}micro[1001];
int dx[] = { 0,-1,1,0,0 };
int dy[] = { 0,0,0,-1,1 };
queue <pair<int, int>> q;//map을 초기화시켜주기 위해
void move() {
    while (m--) {
        for (int i = 0; i < k; i++) {
            if (micro[i].num == 0) continue;
            int x = micro[i].x;
            int y = micro[i].y;
            int num = micro[i].num;
            int dir = micro[i].dir;
            int nx = x + dx[dir];
            int ny = y + dy[dir];
            //약친곳
            if (nx == 0 || ny == 0 || nx == n - 1 || ny == n - 1) {
                num /= 2;
                if (dir == 1 || dir == 3) dir += 1;
                else dir -= 1;
                micro[i].dir = dir;
                micro[i].num = num;
            }
            //이동
            if (map[nx][ny][0] == -1) {
                map[nx][ny][0] = i;
                map[nx][ny][1] = num;
                q.push(make_pair(nx, ny));
            }
            else {//겹치는곳
                int tempi = map[nx][ny][0];
                int tempNum = map[nx][ny][1];
                if (tempNum > num) {//기존값이 더 크면
                    micro[tempi].num += num;
                    micro[i].num = 0;
                    continue;
                }
                else {//기존값이 더 작으면
                    map[nx][ny][0] = i;
                    map[nx][ny][1] = num;
                    micro[i].num += micro[tempi].num;
                    micro[tempi].num = 0;
                }
            }
            micro[i].x = nx;
            micro[i].y = ny;
        }
        while (!q.empty()) {//map초기화
            map[q.front().first][q.front().second][0] = -1;
            map[q.front().first][q.front().second][1] = 0;
            q.pop();
        }
    }
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int test_case;
    cin >> test_case;
    for (int t = 1; t <= test_case; t++) {
        //start
        cin >> n >> m >> k;
        for (int i = 0; i < 101; i++)
            for (int j = 0; j < 101;j++)
                map[i][j][0] = -1;
        for (int i = 0; i < k; i++) 
            cin >> micro[i].x >> micro[i].y >> micro[i].num >> micro[i].dir;
        move();
        //end
        int result = 0;
        for (int i = 0; i < k; i++) {
            if (micro[i].num > 0) result += micro[i].num;
            else continue;
        }
        cout << '#' << t << ' ' << result << '\n';
    }
}
  • 나 혼자 말하고 나 혼자 듣는 말

….