[백준] 1213번 : 팰린드롬 만들기 | C++

2024. 9. 17. 23:30·백준 문제풀이

0. 문제

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

 

주어진 알파벳 대문자로 구성된 문자열을 재배열하여 팰린드롬을 만들어내는 문제입니다. 참고로 팰린드롬이란, 거꾸로 읽어도 같은 (대칭되는) 문자열을 말합니다.


1. 문제풀이 핵심

a) 알파벳 개수 카운팅

  • 주어진 문자열에서 각 알파벳의 개수를 카운트합니다.
  • 팰린드롬을 만들기 위해서는 문자열의 길이가 홀수일 때, 홀수인 알파벳이 정확히 1개여야 하고, 길이가 짝수일 때는 홀수인 알파벳이 없어야 합니다.

b) vector를 스택처럼 활용

  • 팰린드롬을 만들기 위해 알파벳을 양쪽에 대칭으로 배치해야 합니다.
  • 이를 위해 vector를 스택처럼 사용하여 알파벳을 반으로 나누어 저장하고, 다시 역순으로 출력합니다.

c) 홀수인 알파벳을 중간에 배치

  • 문자열의 길이가 홀수인 경우, 홀수 개의 알파벳을 팰린드롬의 중앙에 위치시켜야 합니다.
  • 먼저 알파벳을 반으로 나눈 뒤, 홀수 알파벳을 출력하고 나머지 반쪽을 출력하는 방식으로 팰린드롬을 만듭니다.

d) 사전순으로 가장 앞에 오는 조합 출력

  • map을 사용하여 알파벳의 개수를 카운팅하기 때문에, map의 특성상 키가 자동으로 정렬됩니다.
  • 따라서 알파벳을 사전순으로 정렬할 필요가 없이 map을 순회하는 것만으로도 사전순으로 정렬된 결과를 얻을 수 있습니다.

 


2. 문제풀이에 사용된 개념

 

map을 이용한 알파벳 개수 카운팅

 

  • map을 사용하여 문자열의 각 알파벳이 몇 번 등장하는지 카운트합니다.
  • 키는 알파벳, 값은 그 알파벳의 개수입니다.

 

 

팰린드롬의 특징을 활용한 조건 체크

문자열의 길이에 따라 홀수 개의 알파벳이 몇 개 있어야 하는지 체크합니다.

 

 

vector를 스택처럼 사용하기

팰린드롬을 만들기 위해 문자열의 반만 저장하며 출력하고, 이를 다시 꺼내며 출력합니다.

 

 


 

3. 문제풀이 코드

#include<bits/stdc++.h>

using namespace std;

string s; // 임한수의 영어 이름. 알파벳 대문자로만
map<char, int> m; // 각 알파벳의 개수를 저장
char hol; // 홀수인 알파벳
vector<char> res; // 결과를 저장할 벡터

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

    cin >> s;
    int nameLen = s.size(); 

    // 각 알파벳의 개수를 카운트하여 map에 저장
    for(int i = 0; i < nameLen; i++){
        char cur = s[i];
        auto it = m.find(cur);
        if(it != m.end()){
            it->second++;
        } else {
            m.insert({cur, 1});
        }
    }

    int num = 0; // 홀수인 알파벳 개수

    // 홀수인 알파벳의 개수 찾기
    for(auto i : m){
        if(i.second % 2 != 0) {
            num++;
            hol = i.first; // 홀수인 알파벳을 저장
        }
    }

    // 홀수 개수 알파벳이 1개 이상일 때와 짝수일 때의 조건 체크
    if(nameLen % 2 != 0 && num != 1 || nameLen % 2 == 0 && num != 0 ){ 
        cout << "I'm Sorry Hansoo";
        return 0;
    }

    // 각 알파벳의 절반을 벡터에 저장하여 대칭으로 출력 준비
    for(auto i : m){
        for(int j = 0; j < i.second / 2; j++){
            res.push_back(i.first);
            cout << i.first;
        }
    }

    // 홀수인 알파벳이 있으면 중간에 출력
    if(num) cout << hol;

    // 벡터에서 pop하여 대칭으로 출력
    int resSize = res.size();
    for(int j = 0; j < resSize; j++){
        cout << res.back();
        res.pop_back();
    }
}

 

 

3-1. 코드 로직 설명

  1. 알파벳 개수 카운트
    • 입력받은 문자열에서 각 알파벳의 개수를 map에 저장합니다.
  2. 홀수인 알파벳 체크
    • 문자열의 길이가 홀수인 경우에는 홀수 개의 알파벳이 정확히 1개여야 합니다.
    • 길이가 짝수인 경우에는 모든 알파벳의 개수가 짝수여야 합니다.
    • 이러한 조건이 만족되지 않으면 팰린드롬을 만들 수 없으므로 "I'm Sorry Hansoo"를 출력합니다.
  3. 팰린드롬 만들기
    • 알파벳의 절반을 vector에 저장하면서 출력합니다.
    • 홀수인 알파벳이 있는 경우에는 중간에 출력합니다.
    • vector의 back()과 pop_back()을 사용하여 남은 절반을 꺼내며 역순으로 출력합니다.

 


 

4. 문제풀이에 사용된 함수

map.find(key)

 

  • key가 map에 존재하는지 확인하고, 있으면 해당 요소의 이터레이터를 반환합니다.
  • 존재하지 않으면 map.end()를 반환합니다.

 

 

vector의 back() ,  pop_back()

 

  • back()은 vector의 마지막 요소를 참조합니다.
  • pop_back()은 vector의 마지막 요소를 제거합니다.

** 핵심 = vector를 스택처럼 사용하여 LIFO(Last In, First Out) 구조를 구현할 수 있습니다.

 


 

5. 요약 정리

 

  • 팰린드롬의 조건: 문자열의 길이에 따라 홀수 개의 알파벳이 있을 수 있는지 여부를 판단하고, 이에 따라 팰린드롬을 생성할 수 있는지를 확인합니다.
  • map의 활용: 각 알파벳의 개수를 카운팅하는 데 map을 사용하여 자동 정렬(사전순)과 빠른 검색을 활용했습니다.
  • 팰린드롬 생성: vector를 사용하여 반으로 나눈 문자열을 저장하고, 이를 역순으로 출력하여 팰린드롬을 생성합니다.
  • 중요 포인트:
    • 대칭을 만들기 위해서는 이름의 길이(짝수,홀수)에 따라 홀수인 알파벳이 0개 또는 1개만 있어야 합니다.
    • map을 통해 알파벳 개수를 관리하면서 자동으로 사전순으로 정렬된 결과를 얻을 수 있습니다.

 

'백준 문제풀이' 카테고리의 다른 글

유형 _ 재귀로 분할정복 | 백준 1992번 쿼드트리 [C++]  (0) 2024.10.26
[백준] 1629번 : 곱셈 | C++  (0) 2024.10.02
[백준] 9375번 : 패션왕 신해빈 | C++  (1) 2024.09.17
[백준] 1620 : 나는야 포켓몬 마스터 이다솜 | C++  (2) 2024.09.17
[백준] 2559번 : 수열 | C++  (0) 2024.09.17
'백준 문제풀이' 카테고리의 다른 글
  • 유형 _ 재귀로 분할정복 | 백준 1992번 쿼드트리 [C++]
  • [백준] 1629번 : 곱셈 | C++
  • [백준] 9375번 : 패션왕 신해빈 | C++
  • [백준] 1620 : 나는야 포켓몬 마스터 이다솜 | C++
c_jm
c_jm
  • c_jm
    c_jm
    c_jm

    🎋 어제보다 발전한 오늘

  • 전체
    오늘
    어제
    • 분류 전체보기 (36)
      • 프로젝트 (6)
      • 백준 문제풀이 (19)
      • 프로그래머스 문제풀이 (4)
      • 공부 (1)
      • 문제 해결 (2)
      • 기타 (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    홈서버
    인라인 css
    reverse proxy
    도커
    티스토리 다크모드
    다크모드
    리버스 프록시
    docker-compose
    리버스 프록시 서버
    jquery
    복붙
    docker-compose.yml
    docker
    글자색
    nginx
    도커컴포즈
    html
    백준 #1152 #c++
    코드블럭
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
c_jm
[백준] 1213번 : 팰린드롬 만들기 | C++
상단으로

티스토리툴바