developer-ellen
인간 디버거의 로그 찍기
developer-ellen
전체 방문자
오늘
어제
  • 분류 전체보기 (217)
    • 회고록 (0)
    • 취뽀 및 커리어 여정의 Stack (2)
      • SSAFY 7기 (2)
    • 프로그래밍공부 (24)
      • c++ (0)
      • JAVA (3)
      • Spring (5)
      • design pattern (3)
      • BackDB (1)
      • Servlet&JSP (3)
      • Vue (4)
      • JPA (4)
      • Infra (1)
      • Linux (0)
    • AI (3)
      • papers (3)
      • trend (0)
    • 프로젝트진행 (0)
      • 데이터베이스 (0)
      • 서버개발 (0)
      • 인공지능 (0)
      • 하루정리 (0)
    • 포트폴리오 (0)
    • 알고리즘 (158)
      • 알고리즘문풀 (155)
      • 알고리즘공부 (3)
    • 통계공부 (15)
      • 시계열분석 (15)
      • 회귀분석 (0)
    • CS (14)
      • 컴퓨터네트워크 (4)
      • 운영체제 (8)
      • 데이터베이스 (2)
    • 주저리주저리 (0)
      • 필사 (0)
    • 취업관련정보 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 삼성코테기출
  • 삼성코테구현문제추천
  • 백준파이썬풀이
  • SW역량테스트파이썬풀이
  • ARIMA모형
  • 시계열분석
  • 삼성코테파이썬풀이
  • 삼성코테자바풀이
  • AR모형
  • 카카오코테java풀이
  • BOJ파이썬풀이
  • 통계분석
  • 삼성코테파이썬
  • 통계학
  • c++ 빌더 패턴
  • 카카오코테
  • 운영체제인터럽트
  • 코테파이썬
  • 삼성코테기출자바풀이
  • 삼성코테자바꿀팁
  • Arima
  • c++디자인패턴
  • 삼성코테준비
  • 삼성코테자바준비
  • SW역량테스트파이썬
  • 삼성코테파이썬준비
  • 데이터분석
  • 시계열
  • 삼성코테구현풀이
  • MA모형

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
developer-ellen

인간 디버거의 로그 찍기

알고리즘/알고리즘문풀

BOJ - 전구와 스위치 2138번 (JAVA)

2022. 2. 16. 23:56

❓ 문제 - 백준 전구와 스위치 2138번 - JAVA 풀이법

 

출처 

(https://www.acmicpc.net/problem/2138)

 

2138번: 전구와 스위치

N개의 스위치와 N개의 전구가 있다. 각각의 전구는 켜져 있는 상태와 꺼져 있는 상태 중 하나의 상태를 가진다. i(1 < i < N)번 스위치를 누르면 i-1, i, i+1의 세 개의 전구의 상태가 바뀐다. 즉, 꺼져

www.acmicpc.net

 

 

📝 문제해결법

1. 이 문제는 그리디(탐욕)법으로 풀었다.

  • 우선 왼쪽 -> 오른쪽으로 스위치를 켜면서 지나가면 첫 번째 전구와 마지막 전구만 두 번의 영향을 받으며, 나머지 전구들은 총 3번의 영향을 받게 된다. => 스위치를 켜면(* 범위 내에서) 현재위치-1, 현재위치, 현재위치+1의 영향을 주기 때문이다.
  • 따라서 첫 번째 전구를 켜놓은 상태와 켜놓지 않은 상태로 나눈 후 왼쪽 -> 오른쪽으로 이동하면서 스위치를 켤지 말지 선택한다.
  • 따라서 첫 번째 전구를 켜놓은 상태에서 두 번째 전구부터 마지막 전구까지 for문을 통해 돌면서 현재 (현재 위치 -1) 전구가 현재 내가 목표로 하는 전구 상태 (현재위치-1) 와 같다면 스위치를 키지 않고, 다르다면 스위치를 키면서 상태를 변경해준다. 스위치를 킬 때마다 킨 횟수를 카운트 증가시켜준다. 2번째 전구부터 마지막 전구까지 이와 같은 변화를 준 후, 마지막 전구가 내가 목표로 하는 전구상태의 마지막 전구와 상태가 같다면 카운트 증가횟수와 최솟값을 비교한다. (==> 마지막 전구를 왜 비교 ?? 어차피 첫 번째 전구 ~ 마지막-1 전구까지 다 내가 원하는 상태로 변경시켜줬기 때문에 마지막만 비교하면 됨)
  • 첫 번째 전구를 켜지 않은 상태에서 위 방법과 같이 두 번째 전구부터 마지막 전구까지 스위치를 킬지 말지 정하며 전구의 상태를 변화시켜준다. 그리고 마지막 전구를 내가 원하는 전구상태의 마지막과 비교하며 같다면 스위치를 누른 횟수를 정답 최솟값과 갱신한다.
  • 만약 정답 최솟값이 한번도 갱신되지 않은 상태라면 위 두 경우 모두 원하는 상태로 전구를 변화시키지 못하므로 -1 출력, 최솟값이 갱신되었다면 그 구해진 최솟값을 출력한다.

2) 느낀점

  • 그리디 문제를 많이 안 풀어봐서... 많이 어렵다.. 많은 문제를 접해보면서 그리디 방식의 풀이법을 익숙해지자.
  • 두 경우로 나눠서 풀었는데, 나는 두 경우 중 한 경우만 원하는 전구상태로 변화시킨다라고 인식하여 최솟값 갱신을 구하지 못했다. 그래서 자꾸 100%에서 틀렸습니다. 떠서 왜 그럴까 계속 고민하며 여러 블로그를 참고하니... 두 가지 경우로 전구 상태를 변화 시켜도 둘 다 원하는 전구 상태로 변화가능함... (그러니 카운트의 최솟값을 출력 하도록 했어야.....)
  • 그리디 많이 친해지자 !^^

 

 

💻 소스코드 (구현)

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

public class Main {
    public static int[] dx = {-1, 0, 1};
    public static int n;
    public static char[] data1;
    public static char[] data2;
    public static char[] data3;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());
        String input1 = br.readLine();
        String input2 = br.readLine();
        data1 = new char[n];
        data2 = new char[n];
        data3 = new char[n];

        for(int i=0;i<n;i++){
            data1[i] = input1.charAt(i);
            data2[i] = data1[i];
            data3[i] = input2.charAt(i);
        }

        int ans = Integer.MAX_VALUE;

        int cnt1 = 0;
        int cnt2 = 0;

        data1 = change(data1, 0);
        cnt1++;

        for(int i=1;i<n;i++){
            if(data1[i-1] != data3[i-1]){
                data1 = change(data1, i);
                cnt1++;
            }
        }

        if(data1[n-1] == data3[n-1]){
            ans = Math.min(ans, cnt1);
        }

        for(int i=1;i<n;i++){
            if(data2[i-1] != data3[i-1]){
                data2 = change(data2, i);
                cnt2++;
            }
        }

        if(data2[n-1] == data3[n-1]){
            ans = Math.min(ans, cnt2);
        }


        if(ans == Integer.MAX_VALUE){
            System.out.println(-1);
        } else{
            System.out.println(ans);
        }






    }

    public static char[] change(char[] data, int i){
        for (int d = 0; d < 3; d++) {
            int nx = i + dx[d];
            if (nx < 0 || nx > n - 1) {
                continue;
            }

            if (data[nx] == '0') {
                data[nx] = '1';
            } else {
                data[nx] = '0';
            }
        }
        return data;
    }
}

 

'알고리즘 > 알고리즘문풀' 카테고리의 다른 글

BOJ - 빙산 2573번 (JAVA)  (0) 2022.02.19
SW Expert Academy - 무선 충전 (JAVA)  (0) 2022.02.17
BOJ - 상어 초등학교 21608번 (JAVA)  (0) 2022.02.11
BOJ - 효율적인 해킹 1325번 (JAVA)  (0) 2022.02.10
BOJ - 벽 부수고 이동하기 2206번 (JAVA)  (0) 2022.02.07
    '알고리즘/알고리즘문풀' 카테고리의 다른 글
    • BOJ - 빙산 2573번 (JAVA)
    • SW Expert Academy - 무선 충전 (JAVA)
    • BOJ - 상어 초등학교 21608번 (JAVA)
    • BOJ - 효율적인 해킹 1325번 (JAVA)
    developer-ellen
    developer-ellen

    티스토리툴바