본문 바로가기
Programming/Algorithm

swexpert 미생물

by OKOK 2018. 2. 24.

/* 오후 14:41

정사각형 구역 안에 케이개의 미생물 군집

가로 엔 새로 엔개 총 엔엔 개의 정사각형 셀들

미생물이 벗어나는 것을 방지 오께이. 제한 하나씩 줄이기.

배치되어 있는 예입니다. 오께이

세로위치 가로 위치 미생물 수 이동방향

미생물수는 무엇이지


한시간마다 이동방향에 있는 다음 셀로 이동


미생물군집이 이동 후 약품이 칠해진 셀에 도착하면 군집 내 미생물의 절반이 죽고, 이동 방향이

반대로 바뀝니다.


미생물 수가 홀수인 경우 반으로 나누어 떨어이지 않으므로, 살아남는 수는

원래 미생물 수를 2로 나눈 후 소수점 이하를 버림한 값 오께이 그냥 몫으로 계산하면됩니다.

한마리 있는 경우 군집이 사라지게 됩니다.


이동 후 두 개 이상의 군집이 한 셀에 모이는 경우 군집들이 합쳐지게 됩니다.

이동 방향은 군집들 중 미생물 수가 가장 많은 군집의 이동방향

같은 경우는 없습니다.


엠 시간 이 미생물 군집들을 격리. 엠 시간 후 남아 있는 미생물의 수의 총합을 구하세요.

군집이 변하는 예를 보겠습니다.

엔은 7 케이는 9 입니다.


0초

1초가 지나고 때 셀의 모습

2초가 지나고 셀의 모습


오께이 맵을 하나 만들고, 미생물이 움직이는 것들에 대해서 짜주도록 하겠습니다.

예제를 중심으로 짜도록 하겠습니다. 예제의 이름을 활용해서 짜기.


*/


#include <iostream>

#include <memory.h>

#include <algorithm>

#define SIZE 101

#define SIZE2 1001


using namespace std;


int map[SIZE][SIZE];

int x, y, nx, ny, d, num;

int ans;

int hour;

typedef struct{

int x;

int y;

int num; // 미생물의 수

int d; // 방향

}microbe;

microbe micro[SIZE2];

int N, M, K, T;

int dx[] = { 0,-1,1,0,0 }; // 상 하 좌 우 

int dy[] = { 0,0,0,-1,1 }; // 0 1 2 3 4 예제와 방향 맞춰주기

int max_num, num_sum;


/*

상1 하2 좌3 우4

*/

void init() {

memset(micro, 0, sizeof(microbe) * K);

hour = 0;

ans = 0;

}


int backTurn(int dir) {

if (dir == 1) return 2;

else if (dir == 2) return 1;

else if (dir == 3) return 4;

else if (dir == 4) return 3;

}


void solve() {


while (1) {


//미생물들의 이동

for (int i = 0; i < K; i++) { // 각각의 미생물에 대해서 하나씩 돌립니다.

if (micro[i].num > 0) { // 미생물이 있는 것들만 계산

x = micro[i].x;

y = micro[i].y;

num = micro[i].num;

d = micro[i].d;


nx = x + dx[d];

ny = y + dy[d];

if (nx >= 0 && ny >= 0 && nx < N && ny < N) {

map[nx][ny]++;

micro[i].x = nx;

micro[i].y = ny;

if (nx == 0 || ny == 0 || nx == N - 1 || ny == N - 1) { // 약에 묻으면

micro[i].d = backTurn(d); // 방향이 반대로 되고,

micro[i].num /= 2; // 미생물의 숫자가 반쪽이 됩니다.

}

}

}

}


/*

3개가 있으면 x,y 가 같은 미생물 3개에 대해서 비교를 진행해야 합니다.

max(A, max(B,C)) 이렇게 해야 하는데, 일단 큰 것에 대해서 저장을 한 다음에 다음 것을 찾도록? 

0


1 2 3 4 5 6 

*/

// 합하는 연산을 하도록 하겠습니다. 

for (int i = 0; i < N; i++) {

for (int j = 0; j < N; j++) {

num_sum = 0;

if (map[i][j] >= 2) {

x = i;

y = j;

for (int k = 0; k < K-1; k++) {  // 하나 k 에 저장을 합니다. 

if (micro[k].x == x && micro[k].y == y) {

for (int l = k + 1; l < K; l++) {

if (micro[l].x == x && micro[l].y == y) { // k,l 번째 micro 2개를 이제 비교하면 됩니다.

if (micro[k].num > micro[l].num) { // k 번째가 l 번째 미생물 숫자가 크면

num_sum += micro[l].num;

micro[l].num = 0;

}

else {  // l 번째 미생물 숫자가 크면,

num_sum += micro[k].num;

micro[k].num = 0;

k = l;

}

}

}

micro[k].num += num_sum;

break;

}

}

}

map[i][j] = 0; // 여기서 init 을 해줘도 됨.

}

}


hour++;

if (hour == M) break;

}


for (int i = 0; i < K; i++) {

ans += micro[i].num;

}

}


int main(void) {

cin >> T;

for (int i = 1; i <= T; i++) {

init();

cin >> N >> M >> K;

for (int i = 0; i < K; i++) {

cin >> micro[i].x;

cin >> micro[i].y;

cin >> micro[i].num;

cin >> micro[i].d;

}

solve();

cout << "#" << i << " " << ans << endl;

}


return 0;


 미생물을 이동시키는 함수

합치는 함수가 필요합니다.

합할때는 어떻게 하는지, 포문을 2개 돌리는데,

큰것을 계속해서 남기도록 해야하고, 죽는 것에 대한 처리를 해야합니다.

죽는 것에 대한 처리는 0으로하고, 인덱스를 변경하는것입니다.

오께이. !!!!