※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 2116번 문제인 주사위 쌓기이다.
문제는 아래 링크를 확인하자.

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

 

2116번: 주사위 쌓기

첫줄에는 주사위의 개수가 입력된다. 그 다음 줄부터는 한 줄에 하나씩 주사위의 종류가 1번 주사위부터 주사위 번호 순서대로 입력된다. 주사위의 종류는 각 면에 적혀진 숫자가 그림1에 있는

www.acmicpc.net

맨 아래의 주사위의 밑면을 하나 고정한다면, 쌓은 주사위의 각 층에 사용될 수 있는 옆면의 수는 네 종류로 전부 고정됨을 관찰하자. 이 관찰을 이용하면 각 주사위의 밑면을 고정하는 여섯 경우에 대한 탐색을 통해 문제를 간단히 해결할 수 있다.

 

이를 구현하는 것은 어렵지 않다. (1) 밑면에 있던 수를 마주보는 면에 있는 수로 바꾸고 (2) 앞에서 나온 두 수를 제외한 수 중 최댓값을 더하는 두 작업을 반복하는 코드를 작성하는 것으로 구현할 수 있기 때문이다.

 

아래는 제출한 소스코드이다.

#include <iostream>
using namespace std;

int N;
int psum[6];
int uface[6] = { 1,2,3,4,5,6 };

int mx;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> N;
	while (N--) {
		int a, b, c, d, e, f; cin >> a >> b >> c >> d >> e >> f;
		for (int i = 0; i < 6; i++) {
			int& cur = uface[i];
			if (cur == a) cur = f, psum[i] += max(max(b, c), max(d, e));
			else if (cur == b) cur = d, psum[i] += max(max(a, c), max(e, f));
			else if (cur == c) cur = e, psum[i] += max(max(a, b), max(d, f));
			else if (cur == d) cur = b, psum[i] += max(max(a, c), max(e, f));
			else if (cur == e) cur = c, psum[i] += max(max(a, b), max(d, f));
			else cur = a, psum[i] += max(max(b, c), max(d, e));
		}
	}

	for (int i = 0; i < 6; i++) mx = max(mx, psum[i]);

	cout << mx;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 4883 // C++] 삼각 그래프  (0) 2023.03.10
[BOJ 2618 // C++] 경찰차  (0) 2023.03.10
[BOJ 25378 // C++] 조약돌  (0) 2023.03.09
[BOJ 27866 // C++] 문자와 문자열  (0) 2023.03.09
[BOJ 27865 // C++] 랜덤 게임?  (0) 2023.03.09

※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 2615번 문제인 오목이다.
문제는 아래 링크를 확인하자.

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

 

2615번: 오목

오목은 바둑판에 검은 바둑알과 흰 바둑알을 교대로 놓아서 겨루는 게임이다. 바둑판에는 19개의 가로줄과 19개의 세로줄이 그려져 있는데 가로줄은 위에서부터 아래로 1번, 2번, ... ,19번의 번호

www.acmicpc.net

오목 게임의 한 장면이 주어질 때, 승패가 결정났는지를 먼저 판단하고, 결정났다면 연속으로 다섯개 놓여있는 돌의 위치가 어디인지를 추가로 출력하는 문제이다.

 

바둑판 위에서 일렬로 다섯 개의 돌이 연속으로 위에 놓일 수 있는 모든 가능한 방법에 대해 (1) 해당 다섯 위치에 같은 돌이 올려져 있고, (2) 그 연장선에 해당하는 위치에 그 같은 돌이 올려져있지 않은지를 확인해 승패가 결정났는지를 판단할 수 있다.

 

돌이 다섯 개 연속으로 놓인 곳의 위치를 출력할 때, 가장 위쪽에 놓인 돌이 우선순위가 아닌 가장 왼쪽에 놓인 돌의 위치를 우선적으로 출력해야함에 유의하자.

 

아래는 제출한 소스코드이다.

#include <iostream>
using namespace std;

int board[21][21];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	for (int r = 1; r < 20; r++) {
		for (int c = 1; c < 20; c++) {
			cin >> board[r][c];
		}
	}

	for (int r = 1; r < 20; r++) {
		for (int c = 1; c < 16; c++) {
			if (board[r][c] && board[r][c] == board[r][c + 1] && board[r][c + 1] == board[r][c + 2] && board[r][c + 2] == board[r][c + 3] && board[r][c + 3] == board[r][c + 4] && board[r][c-1]!=board[r][c] && board[r][c+4] != board[r][c+5]) {
				cout << board[r][c] << '\n';
				cout << r << ' ' << c;
				return 0;
			}
		}
	}

	for (int r = 1; r < 16; r++) {
		for (int c = 1; c < 20; c++) {
			if (board[r][c] && board[r][c] == board[r + 1][c] && board[r + 1][c] == board[r + 2][c] && board[r + 2][c] == board[r + 3][c] && board[r + 3][c] == board[r + 4][c] && board[r - 1][c] != board[r][c] && board[r + 4][c] != board[r + 5][c]) {
				cout << board[r][c] << '\n';
				cout << r << ' ' << c;
				return 0;
			}
		}
	}

	for (int r = 1; r < 16; r++) {
		for (int c = 1; c < 16; c++) {
			if (board[r][c] && board[r][c] == board[r + 1][c + 1] && board[r + 1][c + 1] == board[r + 2][c + 2] && board[r + 2][c + 2] == board[r + 3][c + 3] && board[r + 3][c + 3] == board[r + 4][c + 4] && board[r - 1][c - 1] != board[r][c] && board[r + 4][c + 4] != board[r + 5][c + 5]) {
				cout << board[r][c] << '\n';
				cout << r << ' ' << c;
				return 0;
			}
		}
	}

	for (int r = 5; r < 20; r++) {
		for (int c = 1; c < 16; c++) {
			if (board[r][c] && board[r][c] == board[r - 1][c + 1] && board[r - 1][c + 1] == board[r - 2][c + 2] && board[r - 2][c + 2] == board[r - 3][c + 3] && board[r - 3][c + 3] == board[r - 4][c + 4] && board[r + 1][c - 1] != board[r][c] && board[r - 4][c + 4] != board[r - 5][c + 5]) {
				cout << board[r][c] << '\n';
				cout << r << ' ' << c;
				return 0;
			}
		}
	}

	cout << 0;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 27866 // C++] 문자와 문자열  (0) 2023.03.09
[BOJ 27865 // C++] 랜덤 게임?  (0) 2023.03.09
[BOJ 2617 // C++] 구슬 찾기  (0) 2023.03.08
[BOJ 6986 // C++] 절사평균  (0) 2023.03.08
[BOJ 27622 // C++] Suspicious Event  (0) 2023.03.08

※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 2616번 문제인 소형기관차이다.
문제는 아래 링크를 확인하자.

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

 

2616번: 소형기관차

첫째 줄에 기관차가 끌고 가던 객차의 수가 입력된다. 그 수는 50,000 이하이다. 둘째 줄에는 기관차가 끌고 가던 객차에 타고 있는 손님의 수가 1번 객차부터 차례로 입력된다. 한 객차에 타고 있

www.acmicpc.net

dp1[x]를 1번 객차부터 x번 객차까지의 범위에서 K개의 연속한 객차를 하나의 소형기관차를 이용해 끌고갈 때 최대로 옮길 수 있는 손님의 수로 정의하자(단, x는 K보다 크다.). 소형기관차가 객차를 끄는 방법은 x번 객차를 끌거나 끌지 않는 두 가지로 구분할 수 있다. 각 경우의 옮길 수 있는 최대 손님의 수는 dp[x-1]과 dp[x-K], 그리고 x-K+1~x번 객차의 손님의 수의 합을 이용하면 계산해낼 수 있음을 관찰하자. 후자의 값은 prefix sum 배열을 미리 전처리해두는 것으로 빠르게 계산할 수 있다.

 

위와 같은 방식으로 dp2[x] 및 dp3[x] 또한 정의해 그 값들을 구해내자. 이 때 문제의 답은 dp3[N]이 될 것이다.

 

이 방법의 시간복잡도는 \(O(N)\)이다.

 

아래는 제출한 소스코드이다.

#include <iostream>
using namespace std;

int N, K;
int psum[50001];
int dp1[50001];
int dp2[50001];
int dp3[50001];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> N;
	for (int i = 1; i <= N; i++) {
		cin >> psum[i];
		psum[i] += psum[i - 1];
	}
	cin >> K;

	for (int i = K; i <= N; i++) dp1[i] = max(dp1[i - 1], psum[i] - psum[i - K]);
	for (int i = K * 2; i <= N; i++) dp2[i] = max(dp2[i - 1], dp1[i - K] + psum[i] - psum[i - K]);
	for (int i = K * 3; i <= N; i++) dp3[i] = max(dp3[i - 1], dp2[i - K] + psum[i] - psum[i - K]);

	cout << dp3[N];
}
728x90

+ Recent posts