백준 인생은 한 방

KIMYEONGJUN·2025년 11월 30일
post-thumbnail

문제

내가 생각했을때 문제에서 원하는부분

첫째 줄에 로또 문자열의 길이 N(5 ≤ N ≤ 100000)이 주어진다.
둘째 줄에 로또 문자열 S가 주어진다.

로또에 당첨된 경우라면 YES를, 아니면 NO를 출력한다.

내가 이 문제를 보고 생각해본 부분

입력 처리:
BufferedReader를 사용하여 입력 속도를 높였습니다. N과 S를 각각 읽어온다
변수 초기화:
isWinning = false;: 로또 당첨 여부를 나타내는 boolean 변수이다. 
기본값은 false로 설정하고, 당첨 조건을 만족하면 true로 바뀐다.
consecutiveNeighborLength = 1;: 연속해서 이웃한 문자의 개수를 추적하는 변수이다. 
첫 번째 문자는 항상 그 자체로 1의 길이를 가지므로 1로 초기화된다.
문자열 순회:
for(int i = 0; i < N - 1; i++): 문자열 S의 첫 문자부터 마지막 직전 문자(N-1)까지 순회한다. 
이는 항상 현재 문자(S.charAt(i))와 다음 문자(S.charAt(i + 1))를 비교하기 위함이다.
char currentChar = S.charAt(i);와 char nextChar = S.charAt(i + 1);를 통해 현재 문자와 다음 문자를 가져온다.
이웃 문자 확인:
if (Math.abs(currentChar - nextChar) == 1): Math.abs() 함수를 사용하여 현재 문자와 다음 문자의 아스키 코드 값 차이가 1인지 확인한다.
예를 들어, 'C'와 'D'의 경우 abs('C' - 'D')는 abs(67 - 68)이 되어 abs(-1) 즉 1이 된다.
'A'와 'B'도 마찬가지이다.
이 조건을 통해 'A'는 'B'와만 이웃하고, 'Z'는 'Y'와만 이웃하는 경우를 자연스럽게 처리할 수 있다.
만약 두 문자가 이웃한 경우, consecutiveNeighborLength를 1 증가시켜 연속된 이웃 체인의 길이를 늘린다.
만약 두 문자가 이웃하지 않는 경우, 연속성이 끊어졌으므로 consecutiveNeighborLength를 1로 다시 초기화한다. 
이는 nextChar가 새로운 이웃 체인의 시작점이 되기 때문이다.
당첨 조건 확인:
if (consecutiveNeighborLength >= 5): 매번 consecutiveNeighborLength의 값이 갱신되거나 새로 설정될 때마다, 그 값이 5 이상인지 확인한다.
만약 5 이상이라면, 우리는 이미 길이 5 이상의 이웃 부분 문자열을 찾은 것이므로 isWinning을 true로 설정하고 break를 통해 반복문을 즉시 종료한다.
더 이상 문자열을 검사할 필요가 없다.
결과 출력:
반복문이 모두 끝나거나 break로 종료된 후, isWinning 변수의 값에 따라 "YES" 또는 "NO"를 출력한다.
br.close();: BufferedReader는 시스템 자원을 사용하므로, 사용 후에는 반드시 닫아주어 자원 누수를 방지한다.

코드로 구현

package baekjoon.baekjoon_31;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

// 백준 25183번 문제
public class Main1222 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine()); // 로또 문자열의 길이 N 읽기
        String S = br.readLine(); // 로또 문자열 S 읽기

        boolean isWinning = false; // 당첨 여부를 저장할 변수, 초기값은 false
        int consecutiveNeighborLength = 1; // 연속된 이웃 문자의 길이를 세는 변수, 첫 문자는 항상 1로 시작

        // 문자열을 순회하며 이웃한 문자가 연속되는 길이를 확인합니다.
        for(int i = 0; i < N - 1; i++) {
            char currentChar = S.charAt(i);
            char nextChar = S.charAt(i + 1);

            // 현재 문자와 다음 문자가 이웃한 문자인지 확인합니다.
            // Math.abs(currentChar - nextChar) == 1은 두 문자의 아스키 코드 차이가 1이면 이웃으로 간주합니다.
            if(Math.abs(currentChar - nextChar) == 1) {
                consecutiveNeighborLength++; // 이웃하면 연속 길이 증가
            } else {
                consecutiveNeighborLength = 1; // 이웃하지 않으면 연속 길이를 1로 초기화 (다음 문자가 새로운 시작점이 됨)
            }

            // 연속된 이웃 문자의 길이가 5 이상이 되면 당첨 조건을 만족합니다.
            if(consecutiveNeighborLength >= 5) {
                isWinning = true; // 당첨으로 설정
                break; // 더 이상 검사할 필요가 없으므로 반복문 종료
            }
        }

        // 결과 출력
        if(isWinning) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }

        br.close(); // BufferedReader 닫기
    }
}

마무리

코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.

profile
Junior backend developer

0개의 댓글