[백준 C++] 9715 면적구하기

문제

아래 다면체는 1x1x1 정육면체로 만들어져있다. 이 문제에서는 블록이 땅에 닿지 않고 공중에 떠있는 경우는 고려하지않는다(각 칸에는 한개 이상의 정육면체가 차곡차곡 쌓아 올려져있다). 이런 다면체는 숫자들의 행렬로써 주어지며, 각각의 숫자는 각 칸에 쌓아 올려진 정육면체의 수를 의미한다. 0의 경우, 해당 칸에 쌓여진 블록이 없음을 의미한다.

해당하는 그림의 행렬은 아래와 같다.

4231
2101
0001

주어진 행렬로부터 바닥을 포함한 이러한 다면체의 면적을 구하라. 주어진 다면체를 이루는 정육면체들은 모두 맞닿아 있으며, 동떨어진 블록은 없다.

입력

첫째 줄에는 테스트케이스의 수 T가 주어진다.

각 테스트 케이스마다 첫째 줄에는 행렬의 행과 열의 크기인 R과 C(1≤R, C≤50)가 주어진다. 그 다음 줄부터는 차례로 R번째 줄마다 C개의 수가 주어진다. 각 숫자의 크기는 0이상 9이하이다.

출력

각 줄마다 테스트케이스에 주어진 다면체의 면적을 출력하라.

https://www.acmicpc.net/problem/9715

처음에 계산실수로 약간 고생했으나, 직접그려보니 간단했다.
i행 방향의 총갯수를 row, j행방향의 총갯수를 col로 잡고,
2차원배열 block[i][j]에 입력값을 전부넣고, 행,열 높이 3방향의 겹치는 조건을 구해보았다.

  • 행방향 : block[i + 1][j]에 1이상의 값이 들어가있는가
  • 열방향 : block[i][j + 1]에 1이상의 값이 들어가있는가
  • 높이방향 : block[i][j]인 현위치에 2이상의값이 들어가있는가

각각의 경우마다 2씩 카운트해서 (6 x 총블럭의갯수) - 2씩카운트한갯수 => 모든 단면적넓이 로 계산하였다.

중간에 실수를 한구간이 있는데..
위에서 정의한 3가지겹치는 조건을 구현한 부분인데,
모두 같은 if문에 ||연산자로 or로 묶어버린것이다.. 이러면 동시에 병렬적으로 행,열,높이마다 카운트해야하는것을 한번으로 퉁치게된다.
따라서 아래처럼
고치고나니 오류가 사라지고 정상적으로 출력되었다.

오랜만에 정답이다!
아래는 전체 소스코드이다.

#include <bits/stdc++.h>
using namespace std;

int** block;

int main(void) {
	int test;
	cin >> test;
	while (test--) {
		int row, col; //행, 열
		cin >> row >> col;
		block = new int*[row];
		int blockCnt = 0;
		int maxFloor = 0; //최대층 높이
		for (int i = 0; i < row; i++) { //2차원배열에 저장
			block[i] = new int[col];
			string temp = "";
			cin >> temp; //공백없이 입력받으므로 string으로 저장후 하나씩 int로 바꿀것
			for (int j = 0; j < col; j++) {
				int num = temp[j] - '0'; //string에서 하나씩 char를 int로
				blockCnt += num; //블럭갯수카운팅
				if (maxFloor < num) maxFloor = num;
				block[i][j] = num; //값을 전부 기록
			}
		}

		int totalArea = 6 * blockCnt;
		int overlapArea = 0;
		while (maxFloor--) {
			for (int i = 0; i < row; i++) {
				for (int j = 0; j < col; j++) {
					int b = block[i][j];
					//b가 2이상 : 축방향?위로보는 겹치는부분존재
					if (b >= 2) overlapArea += 2;
					//(i+1)이 1이상, b가 1이상 : 행방향 겹치는 부분존재
					if (i + 1 < row && block[i + 1][j] >= 1 && b >= 1) overlapArea += 2;
					//(j+1)이 1이상, b가 1이상 : 열방향 겹치는 부분존재
					if (j + 1 < col && block[i][j + 1] >= 1 && b >= 1) overlapArea += 2;
				}	
			}

			for (int i = 0; i < row; i++) {//층을 하나씩 내리는 작업
				for (int j = 0; j < col; j++) {
					block[i][j] -= 1;
				}
			}
		}
		cout << totalArea - overlapArea << endl;

		delete block; //메모리해제
	}
	return 0;
}

#include <bits/stdc++.h> 에 관한내용은 https://velog.io/@cldhfleks2/%EB%B0%B1%EC%A4%80-C-15500-%EC%9D%B4%EC%83%81%ED%95%9C-%ED%95%98%EB%85%B8%EC%9D%B4-%ED%83%91
이 게시글에 자세히 설명해놓았다.
주로 쓰는 헤더파일을 참조해놓은 헤더파일이다.

좋은 웹페이지 즐겨찾기