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

 

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

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

 

3284번: MASS

The first and only line of input file contains a formula of a molecule whose mass needs to be determined. A formula of a molecule will consist of characters H, C, O, (, ) , 2, 3, ..., 9 only. Its length will be less or equal to 100 characters.

www.acmicpc.net

각 괄호가 닫힐 때마다 대응되는 괄호쌍 안에 담긴 물질의 질량을 합쳐 하나의 값으로 바꿔주고, 한자리 수를 입력받을 때마다 바로 직전에 작업한 값에 곱해 해당 한자리 수를 곱해나가며 문제를 해결하자.

 

괄호의 순서를 관리하는 것은 스택 자료구조를 이용하면 편하게 해낼 수 있다.

 

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

#include <iostream>
#include <string>
#include <vector>
using namespace std;

string s;
vector<int> stk;
int ans;

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

	cin >> s;
	for (auto& l : s) {
		if (l == 'H') stk.emplace_back(1);
		else if (l == 'C') stk.emplace_back(12);
		else if (l == 'O') stk.emplace_back(16);
		else if (l == '(') stk.emplace_back(-1);
		else if (l == ')') {
			int tmp = 0;
			while (stk.back() > -1) {
				tmp += stk.back();
				stk.pop_back();
			}
			stk.pop_back();
			stk.emplace_back(tmp);
		}
		else stk.back() *= l - '0';
	}

	while (!stk.empty()) {
		ans += stk.back();
		stk.pop_back();
	}

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 2079 // C++] 팰린드롬  (1) 2023.08.27
[BOJ 3279 // C++] DOLLARS  (0) 2023.08.26
[BOJ 3283 // C++] BARCODE  (0) 2023.08.24
[BOJ 1799 // C++] 비숍  (0) 2023.08.23
[BOJ 2546 // C++] 경제학과 정원영  (0) 2023.08.22

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

 

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

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

 

3283번: BARCODE

The first and only line of output file should contain a sequence of binary digits represented with bar code given in input file if it can be determined. If a sequence cannot be determined, word ‘UNDETERMINABLE’ should be written to the first line inste

www.acmicpc.net

고려해야 할 케이스가 많은 DP문제이다.

 

먼저 주어진 입력을 잘 처리하여 각 세로줄이 검은 줄('B'로 표기), 하얀 줄('W'로 표기), 모르는 줄('?'로 표기) 중 무엇인지를 구해두자. 이 과정에서 한 세로줄에 'B'와 'W'와 같이 있는 경우가 발견된다면 "UNDETERMINABLE"을 출력해주자.

 

그 뒤, 초기값으로 앞의 두 세로줄이 의미할 수 있는 문자열에 대한 상태를 저장하고, 세번째 세로줄부터 각 세로줄이 해당세로줄을 포함하는 크기 1 또는 2의 문자열로 구간을 나눌 수 있는지의 여부에 따라 DP를 진행해 문제를 해결해주자.

 

아래의 구현에서의 dp배열의 값은 "여러 경우가 존재함"을 의미하는 -1, "경우가 존재하지 않음"을 의미하는 0, "해당 세로줄이 그 한칸으로 기능하는 경우가 가능한 유일한 해석임"을 의미하는 1, "해당 세로줄이 그 전 세로줄과 이어 한칸으로 기능하는 경우가 가능한 유일한 해석임"을 의미하는 2로 구성되어있으니 코드를 읽을 때 참고하자. 여기에서 배열의 값인 1과 2는 dp의 해를 역추적하는 데에도 유용하게 사용할 수 있다. 

 

예외적으로, '?'를 의미하는 세로줄 하나만이 입력이 들어왔을 경우의 답은 "0"임에 유의하자. '?'를 'B'로 해석해도 'W'로 해석해도 해당 문자열은 항상 "0"으로 동일하게 해석되기 때문이다. 이와 같이 복수의 해석이 가능하지만 그 모든 해석이 같은 문자열을 가리키는 경우는 이 경우가 유일하다. (증명은 간단하므로 생략한다.)

 

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

#include <iostream>
#include <vector>
using namespace std;

int N;
string s[5];
bool chk = 1;
char arr[100];
int dp[100][2];
int cnt;

int idx, c;
vector<int> ans;

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

	cin >> N;
	for (int r = 0; r < 5; r++) cin >> s[r];

	for (int i = 0; i < N; i++) {
		bool black = 0, white = 0;
		for (int r = 0; r < 5; r++) {
			if (s[r][i] == '.') white = 1;
			else if (s[r][i] == 'X') black = 1;
		}
		if (black && white) chk = 0;
		else if (black) arr[i] = 'B';
		else if (white) arr[i] = 'W';
		else arr[i] = '?';
	}

	if (!chk) {
		cout << "UNDETERMINABLE";
		return 0;
	}
	
	if (N == 1) {
		cout << '0';
		return 0;
	}

	if (arr[0] == 'B') dp[0][0] = 1;
	else if (arr[0] == 'W') dp[0][1] = 1;
	else dp[0][0] = dp[0][1] = 1;

	if (arr[0] == 'B' && arr[1] == 'B') dp[1][0] = 2;
	else if (arr[0] == 'B' && arr[1] == 'W') dp[1][1] = 1;
	else if (arr[0] == 'B' && arr[1] == '?') dp[1][0] = 2, dp[1][1] = 1;
	else if (arr[0] == 'W' && arr[1] == 'B') dp[1][0] = 1;
	else if (arr[0] == 'W' && arr[1] == 'W') dp[1][1] = 2;
	else if (arr[0] == 'W' && arr[1] == '?') dp[1][0] = 1, dp[1][1] = 2;
	else if (arr[0] == '?' && arr[1] == 'B') dp[1][0] = -1;
	else if (arr[0] == '?' && arr[1] == 'W') dp[1][1] = -1;
	else dp[1][0] = -1, dp[1][1] = -1;

	for (int i = 2; i < N; i++) {
		if (dp[i - 2][1] && (arr[i - 1] == 'B' || arr[i - 1] == '?') && (arr[i] == 'B' || arr[i] == '?')) {
			if (dp[i - 2][1] < 0 || dp[i][0]) dp[i][0] = -1;
			else dp[i][0] = 2;
		}
		if (dp[i - 2][0] && (arr[i - 1] == 'W' || arr[i - 1] == '?') && (arr[i] == 'W' || arr[i] == '?')) {
			if (dp[i - 2][0] < 0 || dp[i][1]) dp[i][1] = -1;
			else dp[i][1] = 2;
		}
		if (dp[i - 1][1] && (arr[i] == 'B' || arr[i] == '?')) {
			if (dp[i - 1][1] < 0 || dp[i][0]) dp[i][0] = -1;
			else dp[i][0] = 1;
		}
		if (dp[i - 1][0] && (arr[i] == 'W' || arr[i] == '?')) {
			if (dp[i - 1][0] < 0 || dp[i][1]) dp[i][1] = -1;
			else dp[i][1] = 1;
		}
	}
	
	if (dp[N - 1][0] == -1 || dp[N - 1][1] == -1 || (dp[N - 1][0] > 0 && dp[N - 1][1] > 0) || (dp[N - 1][0] == 0 && dp[N - 1][1] == 0)) {
		cout << "UNDETERMINABLE";
		return 0;
	}

	idx = N - 1;
	if (dp[idx][1] > 0) c = 1;

	while (idx > -1) {
		ans.emplace_back(dp[idx][c] - 1);
		idx -= dp[idx][c];
		c ^= 1;
	}

	while (!ans.empty()) {
		cout << ans.back();
		ans.pop_back();
	}
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 3279 // C++] DOLLARS  (0) 2023.08.26
[BOJ 3284 // C++] MASS  (0) 2023.08.25
[BOJ 1799 // C++] 비숍  (0) 2023.08.23
[BOJ 2546 // C++] 경제학과 정원영  (0) 2023.08.22
[BOJ 15822 // C++] Ah-Choo!  (0) 2023.08.22

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

 

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

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

 

3282번: ROOMS

The first line of input file contains two integers N, 1 ≤ N ≤ 100, and G separated by a space character. Number N is number of rooms in a hotel and G is number of groups of guests. The next G lines contain numbers of guests in each group – (i+1)th li

www.acmicpc.net

지문에 주어진 호텔의 각 방에 사람을 들이는 과정을 직접 시뮬레이션해 문제를 해결하자. 이는 아래의 구현의 chk변수와 같은 "현재 호텔에 빈 방이 있는지 여부를 표현하는 변수"와 조건문, 반복문 등을 이용해 구현할 수 있다.

 

입력으로 주어지는 N의 크기가 충분히 작으므로 시간 초과의 걱정은 하지 않아도 괜찮다.

 

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

#include <iostream>
using namespace std;

int N, G;
int arr[100];
int idx;
bool chk;

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

    cin >> N >> G;
    while (G--) {
        int M; cin >> M;
        while (M) {
            if (chk) {
                if (arr[idx] == 2) idx++;
                else arr[idx++]++, M--;
            }
            else {
                if (M == 1) arr[idx++] = 1, M--;
                else arr[idx++] = 2, M -= 2;

                if (idx == N) chk = 1, idx = 0;
            }
        }
    }

    for (int i = 0; i < N; i++) {
        cout << arr[i] << '\n';
    }
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 3276 // C++] ICONS  (0) 2023.01.16
[BOJ 3281 // C++] T9  (0) 2023.01.15
[BOJ 27225 // C++] Класс  (0) 2023.01.15
[BOJ 27182 // C++] Rain Diary  (0) 2023.01.15
[BOJ 23320 // C++] 홍익 절대평가  (0) 2023.01.15

+ Recent posts