암호해독기
1 초 | 512 MB | 2012 | 903 | 759 | 48.623% |
문제
방금 도착한 암호문을 해독했는데, 해독에 오류가 없는지 확인해보려 한다. 해독한 문장이 암호문을 해석한 결과로 나올 수 없다면, 그 해독은 잘못된 것이다.
암호문은 0 이상 52 이하의 정수로 이루어져 있다. 0은 띄어쓰기, 1 - 26 범위 안의 수는 A ~ Z, 27 - 52 범위 안의 수는 a ~ z로 해석된다. 암호문은 띄어쓰기를 포함한 모든 철자를 이와 같이 정수로 치환한 후 순서를 무작위로 뒤섞어서 만들어졌다.
입력
첫 번째 줄에는 주어질 수열의 길이 N이 주어진다. (1 ≤ N ≤ 100,000)
두 번째 줄에는 암호문에 해당하는 수 N개가 띄어쓰기와 함께 주어진다.
세 번째 줄에는 평문이 주어진다. 단, 평문의 길이는 N과 같으며, 띄어쓰기로 시작하거나 끝나지 않는다.
출력
평문을 암호화해서 주어진 암호문을 만들 수 있다면 "y", 아니라면 "n"을 따옴표 없이 출력한다.
문제풀이
보자마자 생각이 unordered_map으로 입력받은 숫자를 key로 하여 값을 증가시키고, 스트링을 입력받아 올바른 숫자로 변환한 뒤 감소시켜 0보다 작아지면 n뜨게 하면 된다고 생각했다. 하지만 생각해보니 0보다 작아지는 경우 뿐만 아니라 0이 아닌 경우도 체크를 해주어야 한다. 그럴려면 map을 반복문으로 돌아서 탐색해야 되는데 이럴 바에 그냥 배열 두개 만들어서 비교하는게 편하다고 생각했다.
53크기의 배열 두개를 만든 뒤, 숫자들을 index로 하여 값을 증가시켜 준다.
문자열을 올바르게 변환하여 두 번째 배열의 idx로 하여 값을 증가시켜 준다.
두 값이 다르면 n, 다 통과하면 y를 출력한다.
이거 말고 문자열 입력받는데 보통 cin 그냥 쓰지만 여기는 3번 째 줄을 공백이 있더라도 한번에 입력받아야 했다. cin은 공백이 나올 때까지 입력받고, 그 공백을 버퍼에 저장한다.
getline을 하면 한줄을 입력 받을 수 있다. getline은 엔터가 나오기 전까지 버퍼의 값을 읽어들인다. 엔터가 나오면 엔터를 버리고 그 전까지의 값들을 변수에 할당한다.
이 문제에선 두개를 혼용해서 써야하니, 버퍼에 저장된 엔터를 버려줄 필요가 있다.
#include <iostream>
#include <string>
using namespace std;
void insert(int arr[], char value) {
if(value >= 'A' && value <='Z') {
arr[value-'A'+1]++;
}
else if(value >= 'a' && value <= 'z') {
arr[value-'a'+27]++;
}
else {
arr[value-' ']++;
}
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
int n;
cin >> n;
int arr1[53] = {0, }, arr2[53] = {0, };
for(int i=0; i<n; i++) {
int tmp;
cin >> tmp;
arr1[tmp]++;
}
string s;
cin.ignore();
getline(cin, s);
for(int i=0; i<s.size(); i++) {
insert(arr2, s[i]);
}
for(int i=0; i<53; i++) {
if(arr1[i] != arr2[i]) {
cout << "n";
return 0;
}
}
cout << "y";
return 0;
}
'알고리즘(Algorithm)' 카테고리의 다른 글
[C++] 광물 캐기 (프로그래머스 LEVEL 2) (0) | 2023.09.26 |
---|---|
[C++] IF문 좀 대신 쎠줘 (19637번) (0) | 2023.09.07 |
[C++] 피자 굽기 (1756번) (0) | 2023.08.16 |
[C++] 파티 (1238번) (1) | 2023.08.07 |
[C++] 감소하는 수 (1038번) (0) | 2023.07.08 |