하루하루 꾸준히, 인생은 되는대로

알고리즘

백준 비슷한 단어 2179 C++

긤효중 2022. 7. 13. 01:38

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

 

2179번: 비슷한 단어

첫째 줄에 S를, 둘째 줄에 T를 출력한다. 단, 이 두 단어는 서로 달라야 한다. 즉, 가장 비슷한 두 단어를 구할 때 같은 단어는 제외하는 것이다.

www.acmicpc.net


문제

N개의 영단어들이 주어졌을 때, 가장 비슷한 두 단어를 구해내는 프로그램을 작성하시오.

두 단어의 비슷한 정도는 두 단어의 접두사의 길이로 측정한다. 접두사란 두 단어의 앞부분에서 공통적으로 나타나는 부분문자열을 말한다. 즉, 두 단어의 앞에서부터 M개의 글자들이 같으면서 M이 최대인 경우를 구하는 것이다. "AHEHHEH", "AHAHEH"의 접두사는 "AH"가 되고, "AB", "CD"의 접두사는 ""(길이가 0)이 된다.

접두사의 길이가 최대인 경우가 여러 개일 때에는 입력되는 순서대로 제일 앞쪽에 있는 단어를 답으로 한다. 즉, 답으로 S라는 문자열과 T라는 문자열을 출력한다고 했을 때, 우선 S가 입력되는 순서대로 제일 앞쪽에 있는 단어인 경우를 출력하고, 그런 경우도 여러 개 있을 때에는 그 중에서 T가 입력되는 순서대로 제일 앞쪽에 있는 단어인 경우를 출력한다.


입력

첫째 줄에 N(2 ≤ N ≤ 20,000)이 주어진다. 다음 N개의 줄에 알파벳 소문자로만 이루어진 길이 100자 이하의 서로 다른 영단어가 주어진다.


출력

첫째 줄에 S를, 둘째 줄에 T를 출력한다. 단, 이 두 단어는 서로 달라야 한다. 즉, 가장 비슷한 두 단어를 구할 때 같은 단어는 제외하는 것이다.


처음 생각한 방법(아직 왜 안되는지 해결 못함)->
pair형태로 문자열과 인덱스를 저장하고, 접두사를 구해야 하니깐 정렬(사전순으로, 문자열이 같으면 인덱스가 작은 순서대로)을 한 뒤
i번쨰 i+1번쨰 비교해서 접두사의 최대 길이 갱신하는 식으로 짰는데 75퍼에서 틀렸다.

그래서 완전탐색으로 for문 2개 돌려서 접두사의 최대 길이를 갱신하는 코드 O(N^2)로 제출하였다..


#include <iostream>
#include <string>
using namespace std;
int min(int a,int b){
    if(a<b){
        return a;
    }
    else{
        return b;
    }
}

int max(int a,int b){
    if(a>b){
        return a;
    }
    else{
return b;}
}
int main(void){
    string arr[20001];
    int n;
    int max_size = 0;
    int l = n;
    int r = n;

    cin >> n;
    for(int i = 0;i<n;i++){
        cin >> arr[i];

    }

    for(int i = 0;i<n;i++){
        for(int j = i+1;j<n;j++){
            if(arr[i] == arr[j]){
                continue;
            }
            int length = min(arr[i].size(),arr[j].size());
            if(length == arr[i].size()){
                int temp = 0;
                for(int k = 0;k<arr[i].size();k++){
                    if(arr[i][k] != arr[j][k]){
                        break;
                    }
                    temp++;
                }

                if(temp > max_size){
                    max_size = temp;
                    l = i;
                    r = j;
                }

            }
           else if(length == arr[j].size()){
               int temp = 0;
               for(int k = 0;k<arr[j].size();k++){
                   if(arr[i][k] != arr[j][k]){
                       break;
                   }
                   temp++;

               }

               if(temp > max_size){
                   max_size = temp;
                   l = i;
                   r = j;
               }

           }                  

        }
    }
     int small = min(l,r);
     int big = max(l,r);

    cout << arr[small] << '\n';
     cout << arr[big];

}

 

 

'알고리즘' 카테고리의 다른 글

백준 도어맨 5002 C++  (0) 2022.07.15
백준 1599 민식어 C++  (0) 2022.07.13
백준 11536 줄 세우기 C++  (0) 2022.07.11
백준 9081 단어 맞추기 C++  (0) 2022.07.11
백준 11497 통나무 건너뛰기 C++  (0) 2022.07.11