Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 앱개발
- 코테
- 빅데이터분석
- 백준
- dfs
- SQL
- 구현
- 개발자북클럽
- 정렬
- DP
- ps
- 프로그래머스
- 이진탐색
- 그리디
- 이것이코딩테스트다
- 알고리즘
- Typescript
- 최단경로
- 코딩일기
- react-native
- TS
- bfs
- 코딩테스트
- 타입스크립트
- 노마드코더
- 다이나믹프로그래밍
- 이코테
- 백준온라인저지
- c++
- BOJ
Archives
- Today
- Total
한량처럼 살고 싶다
[백준]백준 18405번(C++) 본문
https://www.acmicpc.net/problem/18405
18405번: 경쟁적 전염
첫째 줄에 자연수 N, K가 공백을 기준으로 구분되어 주어진다. (1 ≤ N ≤ 200, 1 ≤ K ≤ 1,000) 둘째 줄부터 N개의 줄에 걸쳐서 시험관의 정보가 주어진다. 각 행은 N개의 원소로 구성되며, 해당 위치
www.acmicpc.net
문제 해결 과정
- 바이러스는 숫자가 작은 바이러스부터 전염이 되어야 한다. 따라서 우선순위 큐를 이용하여 큐에 바이러스를 저장할 때마다 그 바이러스의 우선순위가 높으면 자동으로 앞으로 오게 한다.
- 1초가 지날 때마다 바이러스가 전염되게 하고, 1초가 종료되면 새롭게 전염된 바이러스의 종류와 위치를 큐에 다시 저장한다. -> 이때 전염되는 과정에서 임시 큐에 새롭게 전염된 바이러스를 저장, 1초가 완전히 종료되면 기존 큐에 임시 큐의 내용을 다시 저장하는 방식을 채택함.
오류 해결 과정 (이 한 문제에서 백준에서 볼 수 있는 대표 결과 4개를 다 보았다)
- 틀렸습니다 -> 시간초과: 우선순위 큐에 저장하는 것까지는 잘했는데, 우선순위큐는 자동으로 내림차순으로 정렬되기 때문에 오름차순 조건을 인자로 넣어주거나, 우선순위 앞에 마이너스를 넣어서 저장해야 오름차순으로 저장이 됨. 하지만 시간초과 발생
- 시간 초과 -> 런타임 에러: 임시 바이러스 저장공간(이때는 벡터였음)에 바이러스를 저장해두고 초기화를 안시켜서 시간이 지날 때마다 엄청난 양의 데이터가 저장되고 있었음.. 난 그것도 모르고 기존 큐에 계속 삽입하니 그걸 전부 전염시키고 조건 확인하느라 시간초과 발생. 그래서 삭제를 진행했지만 런타임에러 발생
- 런타임에러 -> 맞았습니다: 벡터의 앞부분을 삭제하기도 해보고 인덱스로 삭제해보기도 하고 iterator로 순회하면서 삭제해보기도 했는데 계속 에러 발생.. 알아보니 iterator가 순회를 할 때마다 주소값이 바뀌기 때문이라고 한다 (해결책은 여기) 그래서 임시 바이러스 저장공간을 그냥 큐로 선언하고 pop 해줬다.
코드
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <queue>
#include <tuple>
#include <algorithm>
using namespace std;
int N, K; //맵 크기, 바이러스 종류
int** virusMap; //전염될 맵
priority_queue<tuple<int, int, int>> vq;
priority_queue<tuple<int, int, int>> tmp_v;
int S, X, Y; //전염 시간, 위치 좌표
int dir[4][2] = {
{1,0}, //상
{0,1}, //우
{-1, 0}, //하
{0,-1} //좌
};
void input() {
scanf("%d %d", &N, &K);
//맵 메모리 할당
virusMap = new int* [N + 1];
for (int i = 0; i < N + 1; i++) virusMap[i] = new int[N + 1];
//맵 정보 입력
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
int n = 0;
scanf("%d", &n);
virusMap[i][j] = n;
if (n != 0) vq.push(make_tuple(n*-1, i, j)); //바이러스라면 큐에 삽입
}
}
scanf("%d %d %d", &S, &X, &Y);
}
//전염시키기
void infect(int k, int x, int y) {
for (int i = 0; i < 4; i++) {
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if (nx >= 1 && nx <= N && ny >= 1 && ny <= N) {
if (virusMap[nx][ny] == 0) {
virusMap[nx][ny] = k; //해당 위치에 바이러스가 없어야만 전염 됨
tmp_v.push(make_tuple(k*-1, nx, ny)); //새로운 자리를 추가
}
}
}
}
void solution() {
//전파시간 동안 실행
for (int i = 0; i < S; i++) {
while (!vq.empty()) {
int k = get<0>(vq.top());
int x = get<1>(vq.top());
int y = get<2>(vq.top());
vq.pop(); //삭제
infect(k*-1, x, y);
}
while (!tmp_v.empty()) {
vq.push(tmp_v.top());
tmp_v.pop();
}
}
}
int main() {
input();
solution();
printf("%d", virusMap[X][Y]);
}
'PS > 백준' 카테고리의 다른 글
[백준]1439번(C++) (0) | 2023.02.24 |
---|---|
[백준]백준 11404번(C++) (0) | 2023.02.22 |
[백준]백준 1697번(C++) (0) | 2022.10.12 |
[백준]백준 2178번(C++) (1) | 2022.10.09 |
[백준]백준 2667번(C++) (0) | 2022.09.21 |