넘치게 채우기

[BOJ] 1334 - 다음 팰린드롬 수 본문

PS/BOJ

[BOJ] 1334 - 다음 팰린드롬 수

riveroverflow 2025. 3. 13. 14:55
728x90
반응형

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

BOJ - 다음 팰린드롬 수

문제 유형: 문자열 처리, 구현, 조건분기

문제 난이도: Gold V

시간 제한: 1초

메모리 제한: 128MB

 

문제

팰린드롬 수는 앞으로 읽어도, 뒤로 읽어도 같은 숫자이다. 101, 4, 6666와 같은 숫자는 팰린드롬 수이고, 10, 564, 15452와 같은 숫자는 아니다.

어떤 수 N이 주어질 때, N보다 큰 팰린드롬 수 중에서 가장 작은 수를 출력한다.

 

입력

첫째 줄에 N이 주어진다. N은 최대 50자리인 양의 정수이다. 첫 숫자는 0이 아니다.

 

출력

첫째 줄에 문제의 정답을 출력한다.

 

풀이

만약 n의길이가 1이라면, +1한것을 출력하면 끝이다.

(예외: 9는 11을 출력)

 

n의 길이가 홀수인 경우:

우선, 왼쪽 절반 prefix(0 ~ len/2)만 뗀 것을 left라 하자.

left를 뒤집은 것을 right로 초기화 한다.

left + n[len/2] + right가 n보다 크다면(길이가 같기에 사전순비교를 해도 된다), 이를 출력하면 된다.

 

아니라면, 가운데 수를 1 늘리는 것을 시도한다.

  만약 캐리가 발생한다면, left에도 반영해서 올림을 만들어주면 된다.

    만약 캐리때문에 맨 앞까지 0이 된다면, 맨 앞에 1을 붙인다.

     그러고 left + left반전을 붙이면 된다. (ex. 999 -> 1001)

    맨 앞까지 0이된 건 아니라면, right를 변형된 left로부터 복사하여 뒤집어 저장시킨다.

     그러고 left + '0' + right를 출력하면 된다. (ex. 899 -> 909)

 

n의 길이가 짝수인 경우:

왼쪽절반인 left와 그의 반전인 right를 만들고, left + right가 n보다 크다면 출력하면 된다.

아니라면? 홀수에서 가운데에 1을 올린것처럼 left의 맨 끝부터 작업해주면 된다.

 만약 캐리가 left의 맨 앞까지 반영되었다면, "1" + left + left문자열을 만들고, 맨 뒤를 1로 해서 출력하면 된다. (9999 -> 10001)

 그 정도의 캐리는 아니라면, right에 캐리가 반영된 left를 뒤집어서 저장하고, left + right를 출력하면 된다.

 

코드

C++

#include <bits/stdc++.h>

using namespace std;

int main(int argc, char *argv[]) {
    string n;
    cin >> n;

    int len = n.size();
    if (len == 1) {
        if (n == "9") {
            cout << "11\n";
        } else {
            n[0]++;
            cout << n << "\n";
        }
        return 0;
    }
    if (len % 2 == 1) {
        string left = n.substr(0, len / 2);
        string right = left;
        reverse(right.begin(), right.end());

        string temp = left + n[len / 2] + right;
        if (temp > n) {
            cout << temp << "\n";
        } else if (temp[len / 2] <= '8') {
            temp[len / 2]++;
            cout << temp << "\n";
        } else {
            int k = len / 2 - 1;
            while (k >= 0) {
                if (left[k] == '9') {
                    left[k] = '0';
                } else {
                    left[k]++;
                    break;
                }
                k--;
            }
            if (left[0] == '0') {
                left = "1" + left;
                right = left;
                reverse(right.begin(), right.end());
                cout << left + right << "\n";
            } else {
                right = left;
                reverse(right.begin(), right.end());
                cout << left + '0' + right << "\n";
            }
        }
    } else {
        string left = n.substr(0, len / 2);
        string right = left;
        reverse(right.begin(), right.end());
        if (left + right > n) {
            cout << left + right << "\n";
        } else {
            int k = len / 2 - 1;
            while (k >= 0) {
                if (left[k] == '9') {
                    left[k] = '0';
                } else {
                    left[k]++;
                    break;
                }
                k--;
            }
            if (left[0] == '0') {
                string ans = "1" + left + left;
                ans.back() = '1';
                cout << ans << "\n";
            } else {
                right = left;
                reverse(right.begin(), right.end());
                cout << left + right << "\n";
            }
        }
    }

    return 0;
}
728x90
반응형

'PS > BOJ' 카테고리의 다른 글

[BOJ] 2737 - 연속 합  (0) 2025.03.12
[BOJ] 14926 - Not Equal  (0) 2025.03.11
[BOJ] 1507 - 궁금한 민호  (0) 2025.03.10
[BOJ] 17501 - 수식 트리  (0) 2025.03.09
[BOJ] 14916 - 거스름돈  (0) 2025.03.08