[백준] C/C++ 회문 본문

알고리즘_백준/두 포인터

[백준] C/C++ 회문

giron 2021. 10. 24. 12:55
728x90

오랜만에 백준 문제 글을 작성하는 것 같다.😳 

회문.. 오래 걸렸다. 처음 문제를 푸는데 안 풀려서 잠시 미뤄두고 다시 머리를 식히고 푸니 그제야 해결이 되었다.

 

요즘 구현 문제들을 푸는데 상당히 아이디어를 요구하는 방식과 반례 처리? 가 중요한 것 같다는 생각이 든다. 그리고 컨디션이 중요한 느낌..(희한하게 어쩔 때는 잘 풀리는데 안 풀리는 날에는 하나도 안 풀리는 문제 부류...🤣🤫)

 

풀이 과정을 소개해보겠다.

처음에는 재귀문을 통해서 해결하려고 했다. 

시간 초과 풀이

#include <iostream>
#include <string>
using namespace std;

string s;
int l = 0;
int r;
int flag = 0;

int check(int l, int r) {
    while (l < r) {
        if (s[l] == s[r]) {
            l++;
            r--;
            continue;
        }
        else {
            if(check(l+1, r) == 0 || check(l, r-1) == 0){
                return 1;
            }
            else{
                return 2;
            }
        }
    }
    return 0;
}

int main() {
    int n;
    cin >> n;

    for (int i = 0; i < n; i++) {
        cin >> s;
        cout << check(0, s.size()-1) << endl;
        
    }
}

단순해 보여서 시간 복잡도 계산도 안 하고 무지성풀이.. 시간 초과가 나서 재귀를 사용하면 안 될 것 같다는 필을 받았다.

그래서 반복문을 이용했는데 개인적인 생각이지만 이 문제의 핵심은 아래 반례 2개를 처리하냐 인 것 같다. 그 반례 2개는 질문 검색란 맨 마지막 페이지에 있었는데 

입력 : 1 baaba 정답 : 1
입력: 1 aabab 정답: 2

이 두 반례를 충족시키면 웬만해서는 통과할 것이다. 재귀가 안되므로 if문 순서로 진행되는데 s[l+1] == s[r]이 같을 때를 먼저 비교하고 만약 아닐 때, 한번 더 s[l] == s[r-1]을 비교해야 한다. 그 코드 부분만 잘 작성해주면 통과할 것이다. *(s는 input string 변수명)

 

정답 코드

#include <iostream>
#include <string>
using namespace std;

string s;
int l = 0;
int r;
int flag = 0;
int tmp_l, tmp_r;

int check(int l, int r) {
    flag = 0;
    while (l < r) {
        if (s[l] == s[r]) {
            l++;
            r--;
            continue;
        }
        else {
            if(flag == 0 && s[l+1] == s[r]){
                tmp_l = l;
                tmp_r = r;
                l++;
                flag = 3;
                continue;
            }
            else if(flag == 0 && s[l] == s[r-1]){
                r--;
                flag = 1;
                continue;
            }
            else{
                if(flag == 3){
                    l=tmp_l;
                    r = tmp_r-1;
                    flag=1;
                }
                else{
                    flag = 2;
                    break;
                }
            }
        }
    }
    if(flag == 1 || flag == 3){
        return 1;
    }
    else if(flag == 2){
        return 2;
    }
    return 0;
}

int main() {
    int n;
    cin >> n;

    for (int i = 0; i < n; i++) {
        cin >> s;
        cout << check(0, s.size()-1) << endl;
        
    }
}

 

728x90

'알고리즘_백준 > 두 포인터' 카테고리의 다른 글

acmicpc_20922( 겹치는건 싫어)  (0) 2021.02.22
Comments