[백준 BOJ] 17176번 암호해독기 (C++/cpp)

2024. 8. 10. 16:02PS (Program Solving)/BOJ (백준)

문제 설명

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

 

백준 BOJ 17176번 암호해독기 문제 사진

 

접근 방법 - 아스키코드를 활용한 문자열 응용 문제

백준의 17176번 문제는 아스키코드의 원리를 활용하여 해결할 수 있는 문제이다.

해당 문제는, 입력으로 주어지는 숫자들을 일련의 규칙으로 각 알파벳 또는 공백으로 변환할 때 주어진 문자열을 만들 수 있는지에 대한 여부를 구하여 출력해야하는 문제이다.

정답의 여부는, 주어진 숫자들을 알파벳 및 공백으로 변환하였을 때 순서를 적당히 조합하여 입력의 문자열을 만들 수 있는지를 확인해야한다.

따라서, 숫자를 알파벳으로 변환하였을 때 순서와 상관없이 입력받은 문자열의 알파벳 및 공백의 구성과 동일한지 아닌지를 파악해야하는 것이 이 문제의 핵심이라 볼 수 있다.

 

그러하여 필자는 아스키코드의 성질과 정렬 함수를 주로 활용하여, 아래의 방법으로 문제를 해결하려 시도해보았다.

  • 차례로 주어지는 숫자 0~52들을 공백 및 알파벳으로 변환하여, 임의의 문자열 공간(st)에 순차 저장한다.
  • 입력으로 주어지는 문자열(result)와 st에 대해, 각각 정렬을 수행한다.
  • result와 st가 같은지의 여부에 따라 정답을 출력한다.

알파벳의 빈도를 배열에 저장하여 비교하는 방식이 시간 소모가 더 적을 것으로 예상되지만, 저 당시의 필자가 머리를 쓰기 싫어 저리 풀긴 했지마는 이렇게 1차원적으로 푸는 방법도 존재한다.

필자는 위 방식을 아래의 코드로 녹여내어 문제를 풀었으니, 혹여나 해당 문제를 해결하는 데에 어려움을 겪고 있다면 아래의 설명과 코드를 참고해보길 바란다.

필자는 아래의 순서대로 코드를 작성하여 문제를 해결하였다.

 

코드의 실행 순서

1) 문자열의 길이(n)를 입력받는다.

 

2) 암호문을 구성하는 숫자들을 입력받기 이전에, 원활한 해독을 위한 임의의 문자열 st를 선언하고 ""로 초기화한다.

 

3) 해독에 사용할 숫자 n개를 변수 num을 통해 하나씩 입력받으면서, 그와 동시에 아래의 연산을 취한다.

- 만일 num이 0이라면, 이는 공백을 의미한다. 따라서 이때엔, st에 " "값을 추가한다.

- 만일 num이 1 이상 26 이하라면, 이는 대문자를 의미한다. 

이때 num+'A'(65)를 하게 되면 범위가 66('A'+1) ~ 91('Z'+1)로, 이 값으로는 대문자 변형이 제대로 안 될 수도 있기 때문에 (num+'A')-1를 하여 대문자를 만들고 이를 char형으로 st에 추가한다.

- 만일 num이 27 이상 52 이하라면, 이는 소문자를 의미한다.

이때 num+'a'(97)를 하게 되면 범위가 124('a'+27) ~ 149-('z'+27)로, 이 값으로는 소문자 변형이 제대로 안 될 수도 있기 때문에 (num+'a')-27를 하여 소문자를 만들고 이를 char형으로 st에 추가한다.

 

4) 암호문의 해독 예상 결과값(result)을 입력받는다.

이때, 공백도 입력으로 함께 받아야하기 때문에 getline() 함수를 통해서 result를 입력받도록 한다.

 

5) 3)의 연산을 통해 만들어진 임의의 st와 입력으로 주어진 result에 대해서, 각각 정렬을 수행한다.

 

6) result와 st의 알파벳 및 공백의 구성이 같다고 가정한다면, 둘은 5)의 정렬을 통해서 완벽히 같은 문자열이 되어있어야 한다.

따라서 두 문자열이 같다면 구성이 같음을 의미하기 때문에, "y"를 정답으로 출력하도록 한다.

다만 같지 않은 경우엔 구성이 다름을 의미하기 때문에, "n"을 정답으로 출력하도록 한다.

 

7) 6)에서 정답을 출력하였다면, 실행을 종료한다.

반응형

 

성공한 코드

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable: 4996)
#include <iostream>
#include <string>
#include <algorithm>
#define endl '\n'
using namespace std;

// 백준 17176번 코드
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);   cout.tie(NULL);

	int n;
	cin >> n;
	cin.ignore();

	string st = "";
	for (int i = 0; i < n; i++) {
		int num;
		cin >> num;
		cin.ignore();
		
		if (num == 0) {
			st += ' ';
		}
		else if (num >= 1 && num <= 26) {
			st += (char)(num + 'A' - 1);
		}
		else {
			st += (char)(num + 'a' - 27);
		}
	}
	string result;
	getline(cin, result);

	sort(result.begin(), result.end());
	sort(st.begin(), st.end());
	if (result == st) {
		cout << "y" << endl;
	}
	else {
		cout << "n" << endl;
	}
}

 

제출 결과

백준 BOJ 17176번 암호해독기 문제 C++ 제출 결과

(2023.07.01 백준 17176번 문제 제출 결과)

반응형