문제 풀이/백준

[백준] 2866번. 문자열 잘라내기(JAVA)

27200 2025. 3. 13. 20:05

문제

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


풀이(14분)

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int R = Integer.parseInt(st.nextToken()); // R 행
        int C = Integer.parseInt(st.nextToken()); // C 열
        char[][] arr = new char[R][C];

        for(int i = 0; i < R; i++){
            String line = br.readLine();
            for(int j = 0; j < C; j++){
                arr[i][j] = line.charAt(j); // 입력받아 character로 저장
            }
        }

        Set<String> set = new HashSet<>(); // 문자열 중복을 검사
        List<String> list = new ArrayList<>(); // 최초로 만들어진 문자 리스트
        int count = 0; // 정답을 저장할 count
        StringBuilder sb; // 문자열을 만들어갈 스트링빌더
        for(int i = 0; i < C; i++){
            sb = new StringBuilder();
            for(int j = 0; j < R; j++){
                sb.append(arr[j][i]); // 세로로 문자열 만들기
            }
            set.add(sb.toString()); // 최초의 set
            list.add(sb.toString()); // 최초 단어 list 추가
        }

        if(set.size() != list.size()){ // 만약 처음부터 다르다면
            System.out.println(count); // 바로 0 출력
            return;
        }

        for(int i = 1; i < R; i++){
            set = new HashSet<>();
            for(int j = 0; j < C; j++){
                set.add(list.get(j).substring(i,R)); // 하나씩 빼고 문자열 추가
                if(j+1 != set.size()){ // 만약 문자열에 추가된 후에 크기가 다르다면
                    System.out.println(count); // 중복된 것이므로 정답 출력
                    return;
                }
            }
            count++; // 중복이 안 되었다면 count++
        }

        System.out.println(count); // 최종 정답 출력
    }
}

문제 풀이 전략

 

세로로 문자열을 만들어나가야 했기에 초기 시작을 어떻게 해야 할지 고민했다.

 

결론은 모든 문자열을 만들어 둔 뒤 (이때의 계산이 1000 x 1000이 사용된다.) 이것을 잘라나가며 set에 넣는 것이다.

 

가로로 하나씩 날려가며 다음과 같은 작업을 한다.

 

1. 날린 문자열을 set에 추가한다.

2. set의 크기와 현재 몇 열까지 추가되었는지를 비교한다.

3. set의 크기와 열을 가르키는 인덱스+1이 다르다면 중복된 문자열이 존재한다는 소리이다.

4. 중복되었다면 곧바로 정답을 출력한다.

5. 중복되지 않았다면 count++를 해준다.