문제 출처
1. 문제설명
n * n
격자 무늬의 배지에 바이러스를 배양하는 실험을 진행한다.
- 초기에 각 칸에 5만큼의 양분이 들어있으며
m
개의 바이러스로 시작한다.
- 실험 사이클
- 각 바이러스는 본인이 속한
1 * 1
크기의 칸에 있는 양분을 섭취한다.
- 본인의 나이만큼 양분을 섭취한다.
- 같은 칸에 여러 개의 바이러스가 있을 때에는 나이가 어린 바이러스부터 양분을 섭취한다.
- 양분을 섭취한 바이러스는 나이가 1 증가한다.
- 만약 양분이 부족하여 본인의 나이만큼 양분을 섭취할 수 없다면 그 즉시 죽는다.
- 모든 바이러스가 섭취를 끝낸 후 죽은 바이러스가 양분으로 변한다.
- 죽은 바이러스마다 나이를 2로 나눈 값이 바이러스가 있던 칸에 양분으로 추가된다.
- 편의를 위해 소숫점 아래는 버린다.
- 바이러스가 번식을 진행한다.
- 5의 배수의 나이를 가진 바이러스에게만 진행된다.
- 인접한 8개의 칸에 나이가 1인 바이러스가 생긴다.
- 배지 범위를 벗어난 곳에는 바이러스가 번식하지 않는다.
- 과정이 순서대로 끝난 뒤에는 주어진 양분의 양에 따라 칸에 양분이 추가된다.
2. 입/출력
- 격자의 크기
n
, 바이러스의 개수 m
, 총 사이클의 수 k
n
개의 줄에 마지막에 추가되는 양분의 양이 주어진다.
m
개의 줄에 바이러스의 정보가 주어진다.
- 입력으로 주어지는 바이러스의 위치는 모두 서로 다르다.
- k 사이클 이후에 살아남은 바이러스의 수를 구하라
3. 문제 분류
4. 알고리즘 설계
- 바이러스가 양분을 먹고, 번식시키고, 추가 양분을 배분하는 총 3가지 과정으로 나누었다.
- 바이러스 정보 관리
기존 바이러스
, 확산될 바이러스
, 죽은 바이러스
, 새로운 바이러스
로 관리하였다.
- 양분을 먹는 과정에서 죽게되는 바이러스를
죽은 바이러스
벡터에 담는다.
- 양분을 먹는 과정에서 살아남은 바이러스
- 살아남은 바이러스 전체를
새로운 바이러스
에 담는다
- 만약 나이가 5의 배수라면
확산될 바이러스
벡터에 담는다.
- 번식 과정에서 확산될 바이러스의 8가지 방향을 통해 나이가 1인 바이러스를
새로운 바이러스
에 담는다.
기존 바이러스 = 새로운 바이러스
대입을 통해 바이러스 정보를 갱신한다.
5. 전체 코드
4. 소감
- 평소 죽는거나 없애야 하는 정보에 대해 좌표값을
(-1, -1)
로 처리했고, 아래와 같이 for문을 돌면서 건너뛰었다.
for (int i = 0; i < virus.size(); i++) {
info& nxt = virus[i];
if (nxt.x < 0 && nxt.y < 0) continue;
....
}
- 바이러스가 많이 생성되다 보니, 이렇게 하면 시간초과를 발생시켰다.
- 검색을 해봤더니 구현 문제에서는 값을 복사하는 방식을 많이 사용하고 있었다.