BOJ/문자열 (해시,맵)

[C/C++] 백준 - 1213번 (팰린드롬 만들기)

JWonK 2023. 6. 19. 01:45
728x90
반응형

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

 

1213번: 팰린드롬 만들기

첫째 줄에 문제의 정답을 출력한다. 만약 불가능할 때는 "I'm Sorry Hansoo"를 출력한다. 정답이 여러 개일 경우에는 사전순으로 앞서는 것을 출력한다.

www.acmicpc.net

 

문제

임한수와 임문빈은 서로 사랑하는 사이이다.

임한수는 세상에서 팰린드롬인 문자열을 너무 좋아하기 때문에, 둘의 백일을 기념해서 임문빈은 팰린드롬을 선물해주려고 한다.

임문빈은 임한수의 영어 이름으로 팰린드롬을 만들려고 하는데, 임한수의 영어 이름의 알파벳 순서를 적절히 바꿔서 팰린드롬을 만들려고 한다.

임문빈을 도와 임한수의 영어 이름을 팰린드롬으로 바꾸는 프로그램을 작성하시오.

입력

첫째 줄에 임한수의 영어 이름이 있다. 알파벳 대문자로만 된 최대 50글자이다.

출력

첫째 줄에 문제의 정답을 출력한다. 만약 불가능할 때는 "I'm Sorry Hansoo"를 출력한다. 정답이 여러 개일 경우에는 사전순으로 앞서는 것을 출력한다.

 

 


 

▶ 1단계 : 팰린드롬을 만들 수 있는 문자열인지 아닌지 판별하기

팰린드롬은 앞에서 시작하는 문자열이나 뒤에서 시작하는 문자열이 같아야 한다. 그렇다면 팰린드롬이 될 수 없는 문자열이 무엇인지부터 판별해야 해당 문제를 빠르게 해결할 수 있다.

 

팰린드롬이 되려면 우선 앞/뒤에서 같아야 하기 때문에 문자열에 속하는 문자의 개수가 짝수개이어야 한다.

홀수개가 그럼 아예 없어야 하는 걸까? 아니다. 한 개의 문자가 존재하면 가운데에 넣고 그 가운데 문자를 기준으로 팰린드롬을 만들면 가능하다.

 

따라서, 팰린드롬을 만들 수 있는 문자열인지 확인하기 위해서는 홀수개의 문자가 몇 개인지 확인하면 된다. 홀수개의 문자가 2개 이상이라면 해당 문자열은 팰린드롬을 만들 수 없다.

 

 

 

2단계 : 사전순으로 형성되는 첫 번째 팰린드롬 만들기

사전순으로 정렬된 팰린드롬은 어떻게 만들까? 팰린드롬을 반으로 잘라서 생각하면 대충 감이 온다.

→ 사전순으로 가장 뒤에 있는 문자열을 가운데에 고정하고 양 옆으로 다음 우선순위 문자들을 붙이면 된다.

 

예를 들어, AABBCCC라는 문자열이 있으면 CCC라는 문자열을 가운데에 두고 양 옆에 B와 A를 붙인다. 그렇게 형성된 문자열

ABCCCBA가 사전순으로 가장 먼저 오는 팰린드롬이 된다.

 

 

 

[구현 코드]

#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define INF 1e9 + 3
#define endl '\n'

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

string str;
int cnt[200 + 1];

void input(){
	cin >> str;
	for(char s : str) {
		cnt[s]++;
	}
}

bool isMake(){
	int s = 0;
	for(int i='A';i<='Z';i++){
		if(cnt[i] & 1) {
			s++;
			if(s == 2) return false;
		}
	}
	return true;
}

string solution(){
	char mid;
	string result = "";
	for(int i='Z';i>='A';i--){
		if(cnt[i]){
			if(cnt[i] & 1){
				cnt[i]--;
				mid = char(i);
			}

			for(int j=0;j<cnt[i];j+=2){
				result = char(i) + result;
				result += char(i);
			}
		}
	}
	if(mid) result.insert(result.begin() + result.size() / 2, mid);

	return result;
}

int main(){
	fastio;	
	input();
	if(!isMake()) cout << "I'm Sorry Hansoo\n";
	else {
		cout << solution() << endl;
	}
	
	return 0;
}
728x90
반응형