https://www.acmicpc.net/problem/17144
[필자사고]
구현 문제이다. 구현 문제의 가장 큰 해결법은 함수들을 각각의 역할에 맞게 정리하여 세분화 해야 된다는 점이다.
한번에 모든 기능을 다 넣으려고 하면 디버깅 시간이 말도안되게 오래 걸릴 뿐더러 이해하기 어려울 수 있다.
필자는 문제에서 주어진 설명대로 함수들을 나눴고 아래와 같이 코드를 작성하였다.
[해설]
- 입력 처리 (Input 함수):
- R (행 수), C (열 수), T (시간) 값을 입력받습니다.
- 배열 Arr를 R x C 크기로 초기화하고 각 위치의 미세먼지 양을 입력받습니다.
- 공기청정기의 위치를 저장합니다.
- 유틸리티 함수:
- isInside: 주어진 좌표가 배열의 유효 범위 내에 있는지 확인합니다.
- CArr_init: 현재 배열 Arr의 상태를 복사하여 CArr 배열을 초기화합니다.
- 공기청정기 동작 (RotateUp, RotateDown 함수):
- RotateUp: 상단 공기청정기의 순환 동작을 시뮬레이션합니다.
- RotateDown: 하단 공기청정기의 순환 동작을 시뮬레이션합니다.
- 미세먼지 확산 (One_diffusion, All_diffusion 함수):
- One_diffusion: 특정 위치에서 미세먼지가 주변으로 확산되는 것을 계산합니다.
- All_diffusion: 배열 전체의 미세먼지가 확산되도록 합니다.
- 출력 (Print 함수):
- 최종 배열 상태를 출력합니다.
- 시뮬레이션 실행 (GameStart 함수):
- 입력된 시간 T 동안 미세먼지 확산과 공기청정기 동작을 반복합니다.
- 메인 함수:
- Input 함수를 호출하여 초기 입력을 받고, GameStart 함수로 시뮬레이션을 시작합니다.
- 최종 결과를 출력합니다.
아래는 프로그램의 전체 코드입니다.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int dy[4] = { 0,-1,0,1 };
int dx[4] = { 1,0,-1,0 };
typedef pair<int, int> Node;
vector<vector<Node>> Arr;
int R, C, T;
int Result = 0;
int allDustCount = 2;
Node machineIndex = { -1,-1 };
void Input() {
cin >> R >> C >> T;
Arr.resize(R);
for (int i = 0; i < R; i++) {
Arr[i].resize(C);
}
for (int i = 0; i < R; i++) {
for (int k = 0; k < C; k++) {
int num;
cin >> num;
Arr[i][k] = { num,0 };
allDustCount += num;
if (num == -1) {
if (machineIndex.first == -1) {
machineIndex.first = i;
}
else {
machineIndex.second = i;
}
}
}
}
}
bool isInside(int sero, int garo) {
return (sero >= 0 && sero < R && garo >= 0 && garo < C);
}
void CArr_init(vector<vector<Node>>& CArr) {
CArr.clear();
CArr.resize(R);
for (int i = 0; i < R; i++) {
CArr[i].resize(C);
}
CArr = Arr;
for (int i = 0; i < C; i++) {
CArr[0][i] = { 0,0 };
CArr[R - 1][i] = { 0,0 };
CArr[machineIndex.first][i] = { 0,0 };
CArr[machineIndex.second][i] = { 0,0 };
}
for (int i = 0; i < R; i++) {
CArr[i][0] = { 0,0 };
CArr[i][C - 1] = { 0,0 };
}
CArr[machineIndex.first][0] = { -1,0 };
CArr[machineIndex.second][0] = { -1,0 };
}
void RotateUp() {
vector<vector<Node>> CArr;
CArr_init(CArr);
int nowMachine = machineIndex.first;
for (int i = nowMachine-1; i >= 0; i--) {
CArr[i + 1][0] = Arr[i][0];
}
for (int i = 1; i < C; i++) {
CArr[0][i-1] = Arr[0][i];
}
for (int i = 0; i < nowMachine; i++) {
CArr[i][C - 1] = Arr[i + 1][C - 1];
}
for (int i = C - 1; i > 1; i--) {
CArr[nowMachine][i] = Arr[nowMachine][i - 1];
}
Result += CArr[nowMachine][0].first;
CArr[nowMachine][0] = { -1,0 };
for (int i = 0; i <= nowMachine; i++) {
Arr[i] = CArr[i];
}
}
void RotateDown() {
vector<vector<Node>> CArr;
CArr_init(CArr);
int nowMachine = machineIndex.second;
for (int i = nowMachine +1; i<R; i++) {
CArr[i -1][0] = Arr[i][0];
}
for (int i = 1; i < C; i++) {
CArr[R-1][i - 1] = Arr[R-1][i];
}
for (int i = R-2; i >=nowMachine; i--) {
CArr[i+1][C - 1] = Arr[i][C - 1];
}
for (int i = C - 1; i > 1; i--) {
CArr[nowMachine][i] = Arr[nowMachine][i - 1];
}
Result += CArr[nowMachine][0].first;
CArr[nowMachine][0] = { -1,0 };
for (int i = nowMachine; i < R; i++) {
Arr[i] = CArr[i];
}
}
void One_diffusion(int sero, int garo) {
for (int i = 0; i < 4; i++) {
int nextSero = sero + dy[i];
int nextGaro = garo + dx[i];
if (!isInside(nextSero, nextGaro)) continue;
if (Arr[nextSero][nextGaro].first == -1) continue;
int diffusionValue = Arr[sero][garo].first / 5;
Arr[nextSero][nextGaro].second += diffusionValue;
Arr[sero][garo].second -= diffusionValue;
}
}
void All_diffusion() {
for (int i = 0; i < R; i++) {
for (int k = 0; k < C; k++) {
if (Arr[i][k].first > 0) {
One_diffusion(i, k);
}
}
}
for (int i = 0; i < R; i++) {
for (int k = 0; k < C; k++) {
if (Arr[i][k].first != -1) {
Arr[i][k].first += Arr[i][k].second;
Arr[i][k].second = 0;
if (Arr[i][k].first < 0) Arr[i][k].first = 0;
}
}
}
}
void GameStart() {
for (int i = 0; i < T; i++) {
All_diffusion();
RotateUp();
RotateDown();
}
}
int main(void) {
Input();
GameStart();
cout <<allDustCount-Result;
}
설명
- 입력 처리:
- 행(R), 열(C), 시간(T)을 입력받고, 배열을 초기화한 후 공기청정기 위치를 찾아 저장합니다.
- 공기청정기 순환:
- RotateUp과 RotateDown 함수는 각각 상단 및 하단 공기청정기의 순환 동작을 시뮬레이션하여 미세먼지를 처리합니다.
- 미세먼지 확산:
- All_diffusion 함수는 배열 전체의 미세먼지가 확산되는 과정을 처리합니다.
- 시뮬레이션 실행:
- GameStart 함수는 주어진 시간(T) 동안 확산 및 공기청정기 동작을 반복 실행합니다.
이 프로그램을 통해 주어진 시간 동안의 미세먼지 확산과 공기청정기 작동을 시뮬레이션할 수 있습니다. 최종적으로 남아 있는 미세먼지 양을 출력합니다.
'백준 > 삼성기출문제' 카테고리의 다른 글
백준 14500 c++ "테트로미노" -PlusUltraCode- (1) | 2024.10.05 |
---|---|
백준 c++ 14499 "주사위 굴리기" -PlusUltraCode- (1) | 2024.07.05 |
백준 c++ 14890 "경사로" -PlusUltraCode- (0) | 2024.07.02 |
백준 c++ 23288 "주사위 굴리기2" -PlusUltraCode- (0) | 2024.06.28 |
백준 c++ 19236 "청소년 상어" -PlusUltraCode- (0) | 2024.06.24 |