📕문제
회문(回文) 또는 팰린드롬(palindrome)은 앞 뒤 방향으로 볼 때 같은 순서의 문자로 구성된 문자열을 말한다. 예를 들어 ‘abba’ ‘kayak’, ‘reviver’, ‘madam’은 모두 회문이다. 만일 그 자체는 회문이 아니지만 한 문자를 삭제하여 회문으로 만들 수 있는 문자열이라면 우리는 이런 문자열을 “유사회문”(pseudo palindrome)이라고 부른다. 예를 들어 ‘summuus’는 5번째나 혹은 6번째 문자 ‘u’를 제거하여 ‘summus’인 회문이 되므로 유사회문이다.
여러분은 제시된 문자열을 분석하여 그것이 그 자체로 회문인지, 또는 한 문자를 삭제하면 회문이 되는 “유사회문”인지, 아니면 회문이나 유사회문도 아닌 일반 문자열인지를 판단해야 한다. 만일 문자열 그 자체로 회문이면 0, 유사회문이면 1, 그 외는 2를 출력해야 한다.
📕입력
입력의 첫 줄에는 주어지는 문자열의 개수를 나타내는 정수 T(1 ≤ T ≤ 30)가 주어진다. 다음 줄부터 T개의 줄에 걸쳐 한 줄에 하나의 문자열이 입력으로 주어진다. 주어지는 문자열의 길이는 3 이상 100,000 이하이고, 영문 알파벳 소문자로만 이루어져 있다.
📕출력
각 문자열이 회문인지, 유사 회문인지, 둘 모두 해당되지 않는지를 판단하여 회문이면 0, 유사 회문이면 1, 둘 모두 아니면 2를 순서대로 한 줄에 하나씩 출력한다.
🔎문제 해석
굉장히 시간 초과 때문에 고생했다. 머리가 어지러웠다.
어디서 문제였냐 보니까 유사회문 검사할 때 나는 회문 검사 할 때 틀린 부분(대칭점)부터 통째로 문자열을 복사해서 하나하나 검사했는데 그렇게 하니까 시간 초과가 발생했다.
그래서 계속 생각해보니 전체를 검사할 필요가 없었다. 즉 대칭점만 지워서 검사해도 유사회문인지 아닌지를 판단할수있다.
만약 문자열이 "Summuus"라면 대칭점은 2번째에 m과 4번째에 u가 걸릴 것이다.
그래서 검사를 두 번 진행한다.
- 2번째에 m을 지우고 회문 검사
- 4번째에 u를 지우고 회문 검사
이렇게 검사를 두 번 해서 만약 한 번이라도 회문이 된다면 그 문장은 유사회문이라는 뜻이고, 두 번검사를 했음에도, 회문이 아니라면 유사회문이 아닌 문장이다.
💻코드
/*
백준 17609 골드5 회문
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
int n;
vector<string> a;
vector<string> b;
void Copy(int start, int finish, int now, int step);
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
string str;
cin >> str;
int size = str.length();
string cur = str;
int check = 0;
int leftpoint = 0;
int rightpoint = 0;
for (int j = 0; j < size / 2; j++)
{
if (str[j] != str[size - 1 - j])
{
check = 1;
leftpoint = j, rightpoint = size - 1 - j; // 어긋난 경계점을 기록함.
break;
}
}
if (check != 0)
{ // check가 0이 아니라면 회문이 아니라는 뜻. 유사회문 or 아무것도 아님.
string test = cur.erase(leftpoint, 1); //경계점중 왼쪽을 지운 배열
string test1 = str.erase(rightpoint, 1); //경게점 중 오른쪽을 지운 배열
int size = test.length();
bool flag = true;
bool flag1 = true;
for (int k = 0; k < size / 2; k++)
{
if (test[k] != test[size - 1 - k])
{
flag = false;
}
if (test1[k] != test1[size - 1 - k])
{
flag1 = false;
}
}
if (flag == false && flag1 == false) //만약 둘다 false라면 하나도 통과하지 못햇다는 뜻이므로 유사회문이 아님.
{
check = 2;
}
}
cout << check << endl;
}
}
✔느낀 점
- 시간 초과나 메모리 초과가 난다면 고집부리지 말고 처음부터 다시 짜자..
'CodingTest > Baekjoon' 카테고리의 다른 글
[백준 9081] 단어 맞추기 (C++) (0) | 2022.10.02 |
---|---|
[백준 5582] 공통 부분 문자열(C++) (0) | 2022.09.27 |
[백준 6986] 절사평균(C++) (0) | 2022.09.17 |
[백준 20057] 마법사 상어와 토네이도(C++) (0) | 2022.09.15 |
[백준 14500] 테트로미노(C++) (0) | 2022.09.14 |