이마닷의 블로그

[BOJ] 2116:주사위 쌓기 본문

problem-solving

[BOJ] 2116:주사위 쌓기

움나나움 2019. 9. 22. 22:21

 

 

0. 문제

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

 

2116번: 주사위 쌓기

첫줄에는 주사위의 개수가 입력된다. 그 다음 줄부터는 한 줄에 하나씩 주사위의 종류가 1번 주사위부터 주사위 번호 순서대로 입력된다. 주사위의 종류는 각 면에 적혀진 숫자가 그림1에 있는 주사위의 전개도에서 A, B, C, D, E, F 의 순서로 입력된다. 입력되는 숫자 사이에는 빈 칸이 하나씩 있다. 주사위의 개수는 10,000개 이하이며 종류가 같은 주사위도 있을 수 있다.

www.acmicpc.net

 

1. 문제분석

- 이 문제는 주사위 번호가 증가할 수록, 조건을 만족하는 면들 중 가장 값이 큰 면을 선택하면 된다. 따라서 단순한 그리디 알고리즘 문제이다. 또한 조건을 만족하는 모든 경우의 수를 탐색해야 하므로 완전탐색 알고리즘 사용하였다.

 

2. 유의할 점

-  마주보는 두 주사위 면을 한 세트로 묶는 것이 좋다. 이를 위해서 나는 n번 주사위의 n번째 면이 갖는 값을 나타내는 2차원 배열(d[10001][6])을 사용했고, 값 입력 시에 abcdef 순서가 아닌 abcfde 순으로 값을 입력했다.(마주보는면 = (현재 면 + 3) % 6)

-  재귀호출을 통해 모든 경우의 수를 탐색하는데, 이 때 축적되는 최대 면의 값을 계산해주기 위해, 재귀 함수가 호출될 때 해당 면의 값을 더해주고(accum += tmp), 호출이 끝나면 다시 그 값을 제외해주어(accum -= tmp) 다른 경우의 수도 탐색할 수 있도록 했다.

 

3. 소스코드(C++)

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#define endl '\n'
#define INF 987654321
using namespace std;
typedef pair<int, int> ii;

int n, ans, accum;
int d[10001][6];

void go(int now_dice, int prev_val) {
	if (now_dice == n) {
		ans = max(ans, accum);
		return;
	}
	for (int now_side = 0; now_side < 6; now_side++) {
		if (d[now_dice][now_side] != prev_val) continue;
		int tmp = -1;
		for (int j = 0; j < 3; j++) {
			if (j == now_side || j + 3 == now_side) continue;
			tmp = max(tmp, d[now_dice][j]);
			tmp = max(tmp, d[now_dice][j + 3]);
		}
		accum += tmp;
		go(now_dice + 1, d[now_dice][(now_side + 3) % 6]);
		accum -= tmp;
	}
}


int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> n;
	for (int i = 0; i < n; i++) {
		// a b c d e f -> a b c / f d e
		cin >> d[i][0] >> d[i][1] >> d[i][2]
			>> d[i][4] >> d[i][5] >> d[i][3];
	}
	for (int i = 0; i < 6; i++) go(0, d[0][i]);
	cout << ans;
	return 0;
}

 

 

4. 여담

- solved.ac의 문제 기준 상 골드 3에 해당하는 문제였는데, 문제 난이도에 비해선 꽤 쉬운 문제였다. 그래서인지 정답비율도 60%가 넘을 정도로 높은편...

'problem-solving' 카테고리의 다른 글

[BOJ] 12865:평범한 배낭  (0) 2020.12.08
[BOJ] 2573:빙산  (0) 2019.09.29
[BOJ] 2643:색종이 올려 놓기  (0) 2019.09.15
[BOJ] 1162:도로포장  (0) 2019.09.07
[BOJ] 1194:달이 차오른다, 가자.  (1) 2019.08.29
Comments