외발 뛰기 (난이도: 하)

2022. 9. 27. 10:58·알고리즘 (with JAVA)/동적 계획법

1. 문제 설명

(1) 아래의 그림처럼 NxN 크기의 격자에 1부터 9까지의 정수를 쓴 게임판이 있다.

(2) 이 게임의 목적은 게임판의 왼쪽 위칸에서 시작해서 게임판의 맨 오른쪽 아래칸 "끝" 쪽으로 도착하는 것이다.

 

(3) 이때 각 칸에 적혀 있는 숫자만큼 아래쪽이나 오른쪽으로 이동할 수 있으며, 중간에 게임판 밖으로 벗어나면 안 된다.

 

(4) 문제는 게임판이 주어질 때 시작점에서 끝점까지 도달하는 방법이 존재하는 지를 확인하는 것이다.

 

(5) 예를 들어, 아래의 그림처럼 위의 그림에서 마지막 2를 3으로 바꾸면 방법이 없다.

 

 

 

 

2. 입출력 조건 및 예제

입력 조건

(1) 입력의 첫 줄에는 테스트 케이스의 수 C(1<=C<=50)

(2) 그 후 두 번째 줄에는 N(1<=N<=10)의 크기

(3) 그 후 각  줄에는 board(1<=board<=100)를 초기화한다.

 

출력 조건

(1) True는 1로, False는 0으로 출력한다.

 

입력 예제

2
7
2 5 1 6 1 4 1
6 1 1 2 2 9 3
7 2 3 2 1 3 1
1 1 3 1 7 1 2
4 1 2 3 4 1 2
3 3 1 2 3 4 1
1 5 2 9 4 7 0
7
2 5 1 6 1 4 1
6 1 1 2 2 9 3
7 2 3 2 1 3 1
1 1 3 1 7 1 2
4 1 2 3 4 1 3
3 3 1 2 3 4 1
1 5 2 9 4 7 0

 

출력 예제

1

0

 

 

 

 

3. 제약 조건

X

 

 

 

 

4. 가정법

X

 

 

 

 

5. 기저 사례

(1) board판의 범위를 벗어나면

 

 

 

 

6. 코드

: 동적 계획법으로 바꾸기 위해서 먼저 (1)에서는 완전 탐색을 보여주고 (2)에서는 (1)에서의 완전 탐색 중복 계산을

없애는 메모이제이션을 수행하는 것을 보여준다.

 

 

 

(1) 완전 탐색

public class JUMPGAME1 {
    private static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
    private static StringBuilder sb = new StringBuilder();

    private static int[][] board ;
    private static int N;

    public static void main(String[] args) throws IOException {
        StringTokenizer st;
        int C = Integer.parseInt(sc.readLine());

        for(int i=0; i<C; i++) {
            N = Integer.parseInt(sc.readLine());
            board = new int[N][N];

            for(int y=0; y<N; y++) {
                st = new StringTokenizer(sc.readLine());
                for(int x=0; x<N; x++) {
                    board[y][x] = Integer.parseInt(st.nextToken());
                }
            }
            sb.append(solve(0,0)+"\n");
        }
        System.out.println(sb);
    }

    private static boolean solve(int y, int x) {
        // 기저 사례(1): 범위를 벗어나면 false
        if(y>=N || x>=N) return false;

        // "끝" 지점에 도달한 경우 성공
        if(y==N-1 && x==N-1) return true;

        // jump 크기를 가지고 완전탐색 시작.
        int jumpSize = board[y][x];
        return solve(y+jumpSize, x) || solve(y, x+jumpSize);
    }
}

 

 

 

(2) 메모이제이션

public class JUMPGAME2 {
    private static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
    private static StringBuilder sb = new StringBuilder();

    private static int[][] board;
    private static int N;
    private static int[][] cache;
    public static void main(String[] args) throws IOException {
        StringTokenizer st;
        int C = Integer.parseInt(sc.readLine());

        for(int i=0; i<C; i++) {
            N = Integer.parseInt(sc.readLine());
            cache = new int[N][N];
            board = new int[N][N];

            // 캐시 배열 모두 -1로 초기화
            for(int y=0; y<N; y++) {
                for(int x=0; x<N; x++) {
                    cache[y][x] = -1;
                }
            }

            for(int y=0; y<N; y++) {
                st = new StringTokenizer(sc.readLine());
                for(int x=0; x<N; x++) {
                    board[y][x] = Integer.parseInt(st.nextToken());
                }
            }
            sb.append(solve(0,0)+"\n");
        }
        System.out.println(sb);
    }
    private static int solve(int y, int x) {
        // 기저 사례(1): 범위를 벗어나면 false
        if(y>=N || x>=N) return 0;

        // "끝" 지점에 도달한 경우 성공
        if(y==N-1 && x==N-1) return 1;

        // 메모이제이션
        if(cache[y][x] != -1) return cache[y][x];

        // jump 크기를 가지고 완전탐색 시작.
        int jumpSize = board[y][x];
        return cache[y][x] = (solve(y+jumpSize, x) | solve(y, x+jumpSize));
    }
}

 

저작자표시 (새창열림)

'알고리즘 (with JAVA) > 동적 계획법' 카테고리의 다른 글

원주율 외우기 (난이도: 하)  (0) 2022.10.01
합친 LIS (난이도: 하)  (0) 2022.09.29
최대 증가 부분 수열(난이도: 하)  (2) 2022.09.29
삼각형 위의 최대 경로 (난이도: 하)  (0) 2022.09.28
와일드 카드 (난이도: 중)  (0) 2022.09.27
'알고리즘 (with JAVA)/동적 계획법' 카테고리의 다른 글
  • 합친 LIS (난이도: 하)
  • 최대 증가 부분 수열(난이도: 하)
  • 삼각형 위의 최대 경로 (난이도: 하)
  • 와일드 카드 (난이도: 중)
백_곰
백_곰
  • 백_곰
    친절한 코딩
    백_곰
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 알고리즘 (with JAVA)
        • 기본 알고리즘
        • 완전 탐색
        • 분할 정복 알고리즘
        • 동적 계획법
        • 탐욕법
        • 코딩 테스트 기출 문제
        • 코드트리 조별과제
      • 백준 (with JAVA)
        • 완전 탐색
        • 분할 정복
        • 그 외
      • 자바
        • 개발 환경 구축하기
        • 팁
        • 기본적인 개념
        • 컬렉션 프레임워크
        • 프로세스와 쓰레드
        • 지네릭스
        • 람다식
        • 스트림
        • 입출력 IO
        • 네트워킹
        • 열거형(enums)
        • java.lang 패키지
        • java.time 패키지
        • 유용한 클래스들
        • 형식화 클래스들
      • 안드로이드 with 자바
        • 응용 문제들
        • 자잘한 문제들
        • 오류 보고서
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      Arrays
      안드로이드 스튜디오
      outputstream
      코딩테스트
      코딩트리조별과제
      불안정 정렬
      java.lang패키지
      알고스팟
      java.time 패키지
      유용한 클래스
      ServerSocket
      map()
      역직렬화
      중간연산
      스트림
      안정 정렬
      선택 정렬
      InputStream
      serializable
      Collections Framework
      snail
      다형성
      코드트리
      TCP 소켓 프로그래밍
      자바 개념
      람다식
      file
      제자리 정렬
      소켓 프로그래밍
      문자 기반 스트림
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    백_곰
    외발 뛰기 (난이도: 하)
    상단으로

    티스토리툴바