GithubHelp home page GithubHelp logo

rhs0266 / fastcampus Goto Github PK

View Code? Open in Web Editor NEW
622.0 622.0 153.0 60.59 MB

Fast Campus 강의 관련 자료입니다.

License: MIT License

C++ 15.36% Java 74.35% Python 10.29%
coding-test fast-campus problem-solving

fastcampus's People

Contributors

rhs0266 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fastcampus's Issues

이분탐색 함수의 리턴값...

안녕하세요. 호석님.

이분탐색 강의를 들으면서 lower_bound 함수와 upeer_bound 함수가 있는데
이 함수들의 사용시기와 함수에서 리턴해야하는 값(res)의 개념이 자꾸 헷갈리네요.

  1. lower_bound 함수와 upeer_bound 함수를 사용해야 하는 경우
  2. int res = L -1 / int res = R + 1 을 구분하는 것은 가장 왼쪽 인덱스를 리턴해야할 때, 가장 오른쪽 인덱스를 리턴해야할 때로 보이는데 이것을 어떻게 구분할까요...? ㅠ

Numberformat 런타임 에러가 나는 이유를 모르겠습니다.

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

// 1, 2, 3 더하기 6
public class Main {

static int t, n;
static long[] dp;
static BufferedReader br;
static StringBuilder sb = new StringBuilder();

public static void main(String[] args) throws IOException {
    br = new BufferedReader(new InputStreamReader(System.in));
    t = Integer.parseInt(br.readLine());

    pro();

    for (int i = 0; i < t; i++) {
        input();
        sb.append(dp[n]).append("\n");
    }

    System.out.println(sb);
}

static void input() throws IOException {

    br = new BufferedReader(new InputStreamReader(System.in));
    n = Integer.parseInt(br.readLine());

}

static void pro() {

    dp = new long[100001];
    dp[0] = 1;
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 2;
    dp[4] = 3;
    dp[5] = 3;
    for (int i = 6; i < 100001; i++) {
        dp[i] = (dp[i - 2] + dp[i - 4] + dp[i - 6]) % 1000000009;
    }

}

}

BOJ15681 질문입니다.

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

public class Main {
    static StringBuilder sb = new StringBuilder();
    static FastReader scan = new FastReader();

    static int N, R, Q;
    static ArrayList<Integer>[] adj;
    static int[] V, parent;


    static void input() {
        N = scan.nextInt();
        R = scan.nextInt();
        Q = scan.nextInt();
        adj = new ArrayList[N+1];
        for (int i = 0; i <= N; i++) adj[i] = new ArrayList<>();
        for (int i = 0; i < N; i++){
            int u = scan.nextInt(), v = scan.nextInt();
            adj[u].add(v);
            adj[v].add(u);
        }

        V = new int[N+1];
        parent = new int[N + 1];
    }

    static void dfs(int x, int par){
// 정점과 연결된 간선의 갯수가 하나, 즉 leaf노드 일경우?? 정점의 갯수가 1개임을 나타냄
        if (adj[x].size() == 1){
            V[x] = 1;
        }
        for (int y : adj[x]){
            if (y == par) continue;
            parent[y] = x;
            dfs(y, x);
            V[x] += V[y];
        }
    }

    static void pro(){
        dfs(R, -1);
        for (int i = 0; i < Q; i++){
            int x  = scan.nextInt();
            sb.append(V[x]).append('\n');
        }
        System.out.println(sb);
    }

    public static void main(String[] args) {
        input();
        pro();
    }


    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws FileNotFoundException {
            br = new BufferedReader(new FileReader(new File(s)));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}

정점의 갯수를 V[] 배열에 저장하고, 트리를 생성하는 알고리즘을 구성해 보았으나, 시간초과로 인해 오답처리 되었습니다. dfs탐색을 통한 트리 구현이므로 입력의 크기(정점의 갯수)인 N(2~100000) 내에서 시간복잡도를 만족한다고 생각했는데, 어떤부분에서 잘못되었는지 질문 드립니다.

14502 연구소

선생님 안녕하십니까
그래프 2 강의에서 연구소 문제에서 궁금한 것이 생겨 질문드립니다.
image

이 부분이 조합 부분이지 않습니까?
벽이 1 2 3 4가 있으면
1 2 3, 1 2 4, 1 3 4 이런 식으로 하는건데 이렇게 푸는 것을 처음 봐서 여쭤보게 되었습니다.

N과 M에서 조합 부분을 풀 때, visit[i] = true하고 dfs돌리고 visit[i] = false하는 백트래킹이 있지 않습니까? 그거랑 똑같은건지 궁금합니다,,

BOJ 7576 토마토

토마토에 올라와 있는 답안 코드가 잘못 올라온 것 같습니다.

boj 2473 세 용액

강사님 안녕하십니까
드디어 두 포인터 마지막 문제입니다.
이 문제를 일주일 전에 틀려서 풀이를 봤지만 이해가 안 가서,
강의를 다시 보고 왔지만 모르겠습니다..

image

  1. int target = -A[i] 인 점이 궁금합니다.

다른 풀이들을 보면 target = A[i] 그대로 사용하면서
sum = target + A[L] + A[R] 로 하고, sum > 0 이면 R--, sum < 0이면 L++
이런 식으로 풀었습니다.

강사님 풀이를 이해하기 위해 손으로 다 써보았는데,
제가 예상하기로는 target을 - 로 쓴 이유가 R과 L을 옮기는 것 때문에 쓰시는 것 같습니다.

어떻게 보면

//다른 풀이
if ( A[L] + A[R] + target > 0)  

//강사님 풀이
if( A[L] + A[R] > target )

둘 풀이는 같습니다. 강사님은 target을 -target으로 생각해서 결국 왼쪽으로 이항시키면 위 식과 같아지는 것은 알겠습니다..

그런데 왜 이렇게 풀 수 있는지 제 자신이 납득이 안되는 것 같습니다...

예를 들어 두 용액에서는
최대 + 최소 > 0 이나 < 0일 때, 최대 입장이나 최소 입장으로 강사님께서 말씀해주신 부분은 완벽한 납득이 됐습니다.
그런데 위 문제는 A[L} + A[R] 이 target과 무슨 연관이 있는지, 왜 저렇게 두 포인터들을 이동할 수 있는지 모르겠습니다.

두서 없는 질문 정말 죄송합니다..

정렬 강의 부분이 보이질 않아 질문드립니다.

안녕하십니까 정렬 부분 강의를 듣고 싶은데 github에 올려져있는 정렬 부분은 강의에서 찾아볼 수 없어 질문드립니다..
다양한 정렬 응용법 강의에서 N-Queen 문제와 부분 수열의 합 문제가 끝나고 바로 이분 탐색 강의인데 정렬 부분이 보이질 않습니다ㅠㅠ

[백준 -2808] 나무 자르기 질문 드립니다!

안녕하세요 멘토님!

문제 풀이를 하다 결과도 잘 나오고, 시간 복잡도도 초과하지 않는데 문제가 틀렸다고 나와서 답안과 비교해보니
변수를 선언 할 때 long 이 아닌 int 로 선언해서 그랬던 거더라구요.

연산을 할 때는 결국 Int 로 형변환을 해야하는데 long 을 사용해야하는 이유가 궁금합니다.

감사합니다.

static boolean determination(int H) {
        // H 높이로 나무들을 잘랐을 때, M 만큼을 얻을 수 있으면 true, 없으면 false를 return하는 함수
        long sum = 0;
        for (int i = 1; i <= N; i++) {
            if (A[i] > H) {
                sum += A[i] - H;
            }
        }
        return sum >= M;
    }

    static void pro() {
        long L = 0, R = 2000000000, ans = 0;
        // [L ... R] 범위 안에 정답이 존재한다!
        // 이분 탐색과 determination 문제를 이용해서 answer를 빠르게 구하자!
        while (L <= R) {
            int mid = (int) ((L + R) / 2);
            if (determination(mid)) {
                ans = mid;
                L = mid + 1;
            } else {
                R = mid - 1;
            }
        }
        Syst

문제 풀이 질문드립니다.

안녕하세요? 물통과 비슷한 문제가 있어서 아래와 같이 문제를 해결해봤습니다.
혹시 잘못된 부분(ex: 시간복잡도)이나 리팩토링이 필요한 부분이 있는지 알아보기 위해 Issues에 글을 남기게 됐습니다.

백준 - 소수 경로

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

소수를 유난히도 좋아하는 창영이는 게임 아이디 비밀번호를 4자리 ‘소수’로 정해놓았다. 어느 날 창영이는 친한 친구와 대화를 나누었는데:

“이제 슬슬 비번 바꿀 때도 됐잖아”
“응 지금은 1033으로 해놨는데... 다음 소수를 무엇으로 할지 고민중이야"
“그럼 8179로 해”
“흠... 생각 좀 해볼게. 이 게임은 좀 이상해서 비밀번호를 한 번에 한 자리 밖에 못 바꾼단 말이야. 예를 들어 내가 첫 자리만 바꾸면 8033이 되니까 소수가 아니잖아. 여러 단계를 거쳐야 만들 수 있을 것 같은데... 예를 들면... 1033 1733 3733 3739 3779 8779 8179처럼 말이야.”
“흠...역시 소수에 미쳤군. 그럼 아예 프로그램을 짜지 그래. 네 자리 소수 두 개를 입력받아서 바꾸는데 몇 단계나 필요한지 계산하게 말야.”
“귀찮아”
그렇다. 그래서 여러분이 이 문제를 풀게 되었다. 입력은 항상 네 자리 소수만(1000 이상) 주어진다고 가정하자. 주어진 두 소수 A에서 B로 바꾸는 과정에서도 항상 네 자리 소수임을 유지해야 하고, ‘네 자리 수’라 하였기 때문에 0039 와 같은 1000 미만의 비밀번호는 허용되지 않는다.

예제 입력 1
3
1033 8179
1373 8017
1033 1033

구현 방법

  • 첫 번째 소수에서 각 자리를 하나씩 바꿔가며, 두 번째 소수까지의 모든 경우를 탐색한다.
  • 소수를 만족하는 네 자리수는 하나의 정점으로 보고, 자리를 바꾸는 행위가 간선을 통해 이동하는 것으로 볼 수 있다.
  • 따라서 정점과 간선을 구현할 수 있는 Graph를 배열로 구현해볼 수 있다.
  • 만들 수 있는 경우가 여러가지 존재할 수 있고, 그 중 최소한의 단계를 구하기 위해 BFS를 이용하여 문제를 해결한다.
  • 시간 복잡도는 각 자리가 0~9까지 올 수 있으므로 O(10^4)가 된다.

메모리 : 28044kb, 시간 : 344ms

소스 코드 설명

변수 설명

  • 소수 쌍의 수를 입력받기 위해 정수형 N을 선언한다.
  • 각 줄에 소수들을 문자열 형식으로 입력받기 위해, 2차원 String 배열을 선언한다.
  • 각 자리(1의 자리, 10의 자리, 100의 자리, 1000의 자리)를 0부터 9까지 하나하나 바꿔가며 탐색하기 위함
  • 한 번 검사했던 소수는 재검사하지 않기 위해, visit 배열을 선언한다.

함수 설명

solve() 함수
  • 테스트케이스를 입력받고, 모든 케이스에 대한 정답을 계산하는 함수
  • 매 케이스마다 visit 배열을 초기화해준다.
  • 첫 번째 소수에서 두 번째 소수로의 변환을 의미하는, to와 from 변수를 만들어 입력받았다.
  • 이를 bfs 함수의 매개변수로 각각 전달하고, 그 결과를 출력해준다.
bfs() 함수
  • 매개변수(String to, String from)을 입력받아, to에서 from으로 총 몇 단계에 걸쳐 갈 수 있는지 계산하는 함수
  • to 문자열이 from가 같아지면 bfs함수를 종료한다.
  • from에서 to로 바꾸는 과정에서, 바꿀 수 있는 수와 없는 수를 구분하기 위한 함수(isPossible)를 호출
  • 바꿀 수 있을 때만 큐에 넣어, BFS를 진행한다.
isPossible() 함수
  • 매개변수(String number)를 숫자로 변환하여, BFS 탐색이 가능한지 알려주는 함수
  • 1000 미만의 수라면 false를 반환한다.
  • 이미 방문(visit 배열 활용)했다면 false를 반환한다.
  • 소수 판별 함수(isPrime)의 결과를 반환한다.
  • 위에서 false가 반환되지 않았다면, 가능한 수이므로 true를 반환한다.
isPrime() 함수
  • 매개변수(int number)의 수가 소수인지 확인하는 함수
  • 최소 소수인 2부터 number-1까지 탐색하여 나눠떨어지면 false를 반환한다.
  • number-1까지 나눠 떨어지는 수가 없었다면, 소수이므로 true를 반환한다.

깃허브 링크 관련 문의드립니다.

안녕하세요 호석님
혹시 깃헙 다이나믹프로그래밍에서 솔루션 링크없는건(ex: 암호코드) 미완성코드인가요?
오랜 시간 걸려서 해결한 문제인데, 답을 참고해보려고 확인해봤습니다.
현재 솔루션 소스코드의 경우 입력이 1이 들어올 경우 0을 출력하여 오답이 나올 것 같은데
혹시 미완성코드인지 질문드립니다!

배열의 크기 설정에 대한 질문

안녕하세요! 강의 정말 잘 들었습니다. 감사합니다 :)

레포지토리에 올라와 있는 추천 문제를 풀다가 BOJ.2251 물통 문제에 대한 풀이 코드를 보게 되었습니다.
(패캠 풀이코드 링크)
간단한 궁금증인데, 배열의 크기를 205로 초기화 하신 점입니다.

# 풀이 코드 중..
visit = [[[False] * 205 for _ in range(205)] for _ in range(205)]
possible = [0] * 205

# ..

문제에서의 조건은 1<=A, B, C<=200 이기 때문에, 저는 201을 생각했는데 205로 잡은 이유가 있으실까요?
(강의와 연관없는 질문이라면, 죄송합니다! 😢)

항상 감사드립니다!

BOJ 13702 : 이상한 술집 풀이 0 나누기 오류 관련

안녕하세요.
좋은 강의 감사히 보고 있습니다.

이분탐색 연습 문제인 이상한 술집을 풀면서 의문이 생겨 파이썬 풀이를 보았습니다.
문제를 읽어 보았을 때 아래와 같은 입력도 가능하다고 생각되는데요. ( 막걸리의 용량은 231 -1 보다 작거나 같은 자연수 또는 0이라는 조건 때문에 )

1 1
0

과 같은 입력에서 해당 풀이는 0 나누기 오류가 발생할 것으로 생각됩니다.
혹시 제가 질문을 잘 못 이해했다면 너른 양해 부탁드립니다.
감사합니다.

dp2 동물원

선생님 안녕하십니까
dp 2번째 강의를 듣고나서, 연습문제인 동물원을 풀다가 궁금한 점이 생겼습니다.

문제를 4시간정도 써서 풀어보려고 했습니다. 규칙이 찾아지고, 처음으로 dp 문제를 혼자 힘으로 풀었나해서 신나서 점화식이 정말 생각이 안나는 겁니다.

그래서 구글링을 해보았는데, 대부분 사자가 없을 경우, 왼쪽, 오른쪽에 있을 경우 세 가지를 나눠서 풀었습니다. 구글링을 하여 본 풀이들은 이해가 됐지만, 제 풀이도 맞았습니다로 만들고 싶어서 이렇게 질문드립니다. 점화식을 코드로 작성하진 못했지만, 제 풀이대로 하면 경우의 수가 구글링에서 한 풀이들과 답이 똑같았습니다.

image

7한테 접근할 수 있는 경우 : 1,2,3,4,6
dp[4][0] += dp[1][0] + dp[1][1] + dp[2][0] + dp[2][1] + dp[3][1]
-> 12

8한테 접근할 수 있는 경우 : 1,2,3,4,5
dp[4][1] += dp[1][0] + dp[1][1] + dp[2][0] + dp[2][1] + dp[3][0]
-> 12

그래서 dp배열을 나타내보면
1 1
2 2
5 5
12 12
입니다.
그리고 나서 dp배열의 모든 원소를 더해준 뒤 +1을 해줍니다.
여기서 +1은 사자가 한 마리도 없을 경우를 생각한 것입니다.

혹시 몰라서 n이 5일 때도 구글에서 맞은 코드를 가져와 시도해보았습니다.
위의 풀이와 이어서 dp[5][0]와 dp[5][1]이 각각 29가 나옵니다.
그렇다면 29 + 29 + 12 + 12 + 5 + 5 + 2 + 2 + 1 + 1 = 98이 나옵니다.
여기서 +1을 해주면 99로 같은 답이 나오게 됩니다.

제 풀이를 정리하면서 왜 이 풀이는 dp 풀이식으로 적절하지 않은가?

  1. 강의대로 dp[N][0] + dp[N][1] 을 더해야 값이 나와야 하는데 제 풀이는 모든 원소를 다 더해서 값을 구해야한다?

  2. 점화식을 만드려고 이것저것 다 해보았습니다.,, 정말 귀찮은게 아니라 공통점을 찾으려고 했는데도 이 경우가 맞으면 다른 경우가 안되고 그랬었습니다. 아무튼 점화식을 만들 수 없어서?
    였습니다,,

꼭 혼자 풀고 싶어서 2~3일 잡고 있었는데, 이제 놓아주고 싶어서 이렇게 강사님께 여쭤봅니다,,
그리고 강사님도 해당 문제를 보고 구글 블로그들과 같이 사자가 없을 경우, 왼쪽, 오른쪽에 각각 있을 경우 세 가지로 나눠서 dp[n][0] dp[n][1] dp[n][2]로 푸셨는지 궁금합니다.

그리고 해당 문제는 계단 오르기로 뭔가 dp 첫번째 강의에서는 규칙성이 눈에 보여서 풀었는데 이번 dp 두번째 강의 중 계단 오르기 관련 연습문제들은 어떠한 특별한 경우를 잘 나눠서 거기 안에서 규칙성을 찾는 것이 포인트 같은데 제가 느낀 것이 맞는지 궁금합니다!!

읽어주셔서 감사합니다

BOJ 1939

강사님 안녕하십니까
이번에 이분 탐색 강의 다 듣고 기본 문제 다 풀고 골드 난이도 문제 풀고 있습니다.
그 와중에 1939번이라는 문제를 풀다가 도저히 어려워서 힌트를 봤습니다.
힌트를 보다가 어 이거 호석님이 말씀하신 parametric search에서
문제의 순서를 바꿔서(중량이 주어질 때, 이동할 수 있냐?) 이렇게 풀면 된다는 풀이가 생각이 나서
바로 풀었는데 맞았습니다... 호석님의 풀이를 생각못했다는 점이 너무 아쉽지만 이번 문제를 통해 매개 변수 탐색 절대 안 잊을 것 같아요. 그리고 기본 문제 픽 너무 좋은 것 같습니다
이번 issue는 정말 가르침 잘 받고 있다고 말씀드리고 싶어서 썼습니다!!
항상 물어봐도 답도 잘해주시고 너무 감사합니다 호석님!!
즐거운 밤 되세용

선 시청 후 문제풀이 vs 선 도전 후 시청

안녕하세요 강사님!
먼저 양질의 강의에 대해 정말 감사드립니다!

질문은 제목과 같습니다!
수강 후 문제풀이 도중 재 수강 VS 도전 후 풀이보고 재도전 후 재 수강

강사님은 어떤 방식을 추천하시는지 궁금합니다!

20363 부동산 답안 질문드립니다!

답안 코드가 도저히 이해가 안되서 질문 남깁니다!

pro 메소드 부분이 좀 이상한 것 같은데
혹시 정상적인 코드가 맞을까요 ...?

알고리즘 이론 관련 질문 있습니다..!

dave lee 강사님의 강의를 듣다가 궁금해서 왔습니다..( dave lee 강사님 한테 질문을 해야하는데 깃허브 링크가 없어서 이렇게 질문 남깁니다..!)

강사님이 설명해준 퀵 정렬 코드입니다!
퀵 정렬의 장점이 추가적인 메모리가 필요하지 않다는게 장점으로 알고 있는데
이 코드에서는 leftArr와 rightArr, 그리고 이렇게 분할 된 것들을 한 번에 모아주는 sortList 라는 배열까지 불필요한 메모리들을 사용하는데 알고리즘을 푸는 과정에서도 이렇게 풀어도 되는지 의문입니다!!

import java.util.ArrayList;
import java.util.Arrays;

public class MergeSort {
public ArrayList sortFunc(ArrayList dataList) {
if(dataList.size() <= 1) {
return dataList;
}

    int pivot = dataList.get(0);

    ArrayList<Integer> leftArr = new ArrayList<Integer>();
    ArrayList<Integer> rightArr = new ArrayList<Integer>();

    for(int i = 1; i < dataList.size(); i++) {
        if(pivot > dataList.get(i)) {
            leftArr.add(dataList.get(i));
        } else {
            rightArr.add(dataList.get(i));
        }
    }
    ArrayList<Integer> sortList = new ArrayList<Integer>();
    sortList.addAll(sortFunc(leftArr));
    sortList.addAll(Arrays.asList(pivot));
    sortList.addAll(sortFunc(rightArr));

    return sortList;
}

public static void main(String[] args) {
    ArrayList<Integer> dataList = new ArrayList<>();
    MergeSort mergeSort = new MergeSort();
    for(int i = 0; i < 100; i++) {
        dataList.add((int)(Math.random() * 100));
    }
    System.out.println(mergeSort.sortFunc(dataList));
}

}

다이나믹 프로그래밍 첫 번째 강의 중 11052 카드 구매하기 문제

안녕하십니까 선생님 dp 첫 번째 강의에서 연습 문제 중에 궁금한 점이 생겨 질문 드립니다,,
많은 질문을 드려 죄송합니다.. 이때까지 dp공부를 미루다가 선생님 강의를 통해 꼭 코테 수준까지는 마스터하고 싶어서 이렇게 질문 드립니다

아래의 이미지를 보시면 제가 가짜 문제를 만든 뒤, 1번과 같이 공통점을 찾기 위해 N이 2 ~ 6까지 해보았습니다. 한 2시간 가량 문제를 봐도 규칙성이 전혀 보이질 않았습니다. 그래서 구글링을 통하여 2번과 같은 점화식이란는 것을 알았습니다. 그러나 선생님처럼 가짜 문제를 만든 뒤, 초기값을 구하고 점화식 구해내는 순서로 문제를 해결하고 싶습니다.,,

다른 블로그들을 봐도 1번 카드를 살 때 i-1, 2번 카드를 사면 i-2 이런식으로 설명이 되어서 해당 문제의 규칙성은 도대체 어떤 것인지 궁금합니다,,

image

별개로 강사님께 여쭙고 싶은게 있습니다,,
제가 강의를 듣고 지금 한 4,5문제 정도 시도를 했는데 거의 90%를 구글링을 하면서 아,, 결국 점화식이 이거였구나.. 라고 하는데 dp는 이렇게 하는 공부가 맞는건가요,,?? 다른 dfs나 bfs 같은 것은 한 4~5문제만 풀어도 아 이런거구나 하고 감이 오는데 dp는 전혀 아니어서요... 감이 1도 안잡힙니다ㅠㅠ 첫 번째 강의도 2번 정도 보고 예제가 확실하게 이해 쏙 박혔는데도 적용을 못하네여,,

p15970 화살표 그리기 질문입니다.

제출번호 35000475

위의 제출번호의 코드에서는 틀렸습니다.로 나오는데 주어진 예시는 다 맞는데 왜 틀린건지 전혀 모르겠습니다ㅠㅠ

코드
`
import java.util.*;

//화살표 그리기
public class Main {

static int n;
static int ans=0;
static int[][] point;

public static void main(String[] args) {
	
	Scanner sc = new Scanner(System.in);
	
	n=sc.nextInt();
	
	point=new int[n][2];
	
	for(int i=0;i<n;i++) {
		
		point[i][0]=sc.nextInt();
		point[i][1]=sc.nextInt();
		
	}
	
	pro();
	
	System.out.println(ans);
	
	// TODO Auto-generated method stub

}

static void pro() {
	
	for(int idx=0;idx<n;idx++) {
		//흰색
		if(point[idx][1]==1) {
			
			int tmpans=Integer.MAX_VALUE;
			for(int i=0;i<n;i++) {
				if(point[i][1]==1) {
					if(Math.abs(point[i][0]-point[idx][0])==0) continue;
					tmpans=Math.min(tmpans, Math.abs(point[i][0]-point[idx][0]));
				}
			}
			if(tmpans==Integer.MAX_VALUE) continue;
			
			ans+=tmpans;
			
		}
		//검은색
		else {
			
			int tmpans=Integer.MAX_VALUE;
			for(int i=0;i<n;i++) {
				if(point[i][1]==2) {
					if(Math.abs(point[i][0]-point[idx][0])==0) continue;
					tmpans=Math.min(tmpans, Math.abs(point[i][0]-point[idx][0]));
				}
			}
			
			if(tmpans==Integer.MAX_VALUE) continue;
			
			ans+=tmpans;
		}
	}
	
}

}
`

정렬파트 카드 문제 질문드립니다!

안녕하세요?
카드 문제의 Arrays.sort()의 경우 long 타입이어서 시간 복잡도가 N^2이 나올 것 같은데,
강의 내용과 같이 N log N이 맞는지 궁금하여 질문드립니다!

이분탐색 문제 2343번 관련 질문입니다.

import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class BOJ2343 {

static int N,M;
static int [] lessons;

static void input(){
    FastScan fc = new FastScan();

    N = fc.nextInt();
    M = fc.nextInt();

    lessons = new int [N];
    for(int i =0; i < N; i++) {
        lessons[i] = fc.nextInt();
    }
}

static boolean determination(int len) {
    int cnt = 1, sum = 0;
    for (int i = 0; i < N; i++) {
        if (sum + lessons[i] > len) {
            cnt++;
            sum = lessons[i];
        } else {
            sum += lessons[i];
        }
    }
    return cnt <= M;
}

static void solve(){
    Arrays.sort(lessons);

    int L = lessons[N-1];
    int R = 1000000000;
    int result = 0;

    while(L<=R) {
        int mid = (L+R) / 2;
        if(determination(mid)) {
            result = mid;
            R = mid - 1;
        }else {
            L = mid + 1;
        }
    }

    System.out.println(result);
}

public static void main(String[] args) {
    input();
    solve();
}


static class FastScan{
    BufferedReader br;
    StringTokenizer st;

    public FastScan(){
        br = new BufferedReader(new InputStreamReader(System.in));
    }

    public FastScan(String name) throws FileNotFoundException {
        br = new BufferedReader(new FileReader(name));
    }

    String next() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        String str = "";
        try {
            str = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }
}

}

와 같이 코드를 작성하여 백준에 제출했는데 틀렸다고 나오고 있습니다...
답안과 비교해본 결과 배열 인덱스 설정부분과 L값 설정부분을 제외하고는 동일한것으로 보이는데... 어떤 케이스에 틀렸는지 감이 오지 않아 질문드립니다.

BOJ 2003

강사님 안녕하십니까
강의 잘 듣고 있습니다 강의 덕분에 dp문제를 이제 좀 넉넉하게 푸는 것 같습니다!
다름이 아니라 두 포인터 강의를 듣고 2203문제를 푸는데 궁금한 점이 생겨 질문드립니다.

틀린 것

while (true) {

//            System.out.println(s + " " + e);
            //if와 else if 구분 잘해야함
            //sum < M할 때, sum += arr[e++] 해주면서 sum == K가 될 수 있음
            if(e == N) break;

            if(sum >= M){
                sum -= arr[s];
                s++;
            }
            else {
                sum += arr[e++];
            }

            if(sum == M){
                cnt++;
            }
            //왜 e == N일떄 멈춰도되나?
            //e가 잇는상태에서 s가 계속 가면서 답이 될 수 있지않을까?
            //절대 아니다. 왜냐하면 이미 Sum보다 작으면서 e == N이면
            //s가 늘어난다하면 당연히 뺄텐데 여기서 이미 sum보다 작은데 뺴면 더 작아지니까 답이 안됨 어차피

        }

맞은 것


 while (true) {

            //if와 else if 구분 잘해야함
            //sum < M할 때, sum += arr[e++] 해주면서 sum == K가 될 수 있음

            if(sum >= M){
                sum -= arr[s];
                s++;
            }
            else if(e == N){
                break;
            }

            else{
                sum += arr[e++];
            }
            
            if(sum == M){
                cnt++;
            }
        }

sout으로 s와 e의 좌표를 모두 찍어보고 손으로 다 해봤는데 왜 틀린지 모르겠습니다,,

그리고 혹시 두 포인터에서 중요한 부분은 범위 나누기일까요??
위 문제도 구글링해서 힌트를 얻은 것입니다.. 범위 나누는 데에 있어서 꼭 알아야 하는 부분이 있을까요?
강의 내용은 이해가 다 됐는데 막상 풀려고 하니 범위 나누기가 어렵습니다.

11403 경로 찾기

안녕하십니까 선생님
그래프 1 강의를 보고 기본 문제를 푸는 중에 궁금한 것이 생겨 여쭤봅니다.

public class Main {
    static int atoi(String str){
        return Integer.parseInt(str);
    }
    static int rel[][];
    static int arr[][];
    static boolean visit[];
    static boolean recur[];
    static int N;
    public static void main(String args[]) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        N = atoi(br.readLine());
        rel = new int[N+1][N+1];
        arr = new int[N+1][N+1];

        for (int i = 1; i <= N; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= N; j++) {
                arr[i][j] = atoi(st.nextToken());
            }
        }

        for (int i = 1; i <= N; i++) {
            //start시점마다 visit배열을 초기화
            visit = new boolean[N + 1];
            recur = new boolean[N + 1];
            dfs(i);
            for (int j = 1; j <= N; j++) {
                if(recur[j]){ //recur 대신에 visit
                    rel[i][j] = 1;
                }
            }
        }

        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= N; j++) {
                System.out.print(rel[i][j] + " ");
            }
            System.out.println();
        }
    }
    static void dfs(int start){
        //dfs경로를 감
        visit[start] = true;

        for (int i = 1; i <= N; i++) {
            if(visit[i]) continue;
            if(arr[start][i] == 0) continue;
            recur[i] = true;
            dfs(i);
        }
    }
}

제가 처음에 접근할 때 recur 대신에 visit라는 주석이 있는 곳에 recur[j]가 아닌, visit[i]를 넣었습니다. 그랬더니 2 -> 7 -> 3이 될 때, 2로 다시 오지 못하는데 2가 갈 수 있다고 나오고,
recur[i]를 넣었더니 1 -> 4 -> 5 -> 1 마지막 1로 갈 수 있는데 가지 못한다고 나옵니다.
왜 둘 다 안되는지 디버깅을 돌려서 알고 있습니다.
또한, dfs 메소드 파라미터를 인자를 두 개 사용하여 x, y좌표 격자형처럼 문제를 해결했습니다.
문제를 해결할 때, 아래와 같이 이중포문을 써야합니다.
그러나 저는 포문 한개만을 사용하여 dfs를 돌리고 싶습니다,,
제 처음 풀이가 아예 틀렸는지, 아니면 해결 방법이 있다면 힌트를 얻고자 질문드립니다.

for (int i = 1; i <= N; i++) {
            //start시점마다 visit배열을 초기화
            visit = new boolean[N + 1];
            for (int j = 1; j <= N; j++) {
                if(arr[i][j] == 1 && !visit[j])
                    dfs(i, j);
            }
}

완전탐색) BOJ 2309 - 아홉난쟁이

안녕하세요.
강의에서 들었던 내용을 바탕으로 위의 문제를 (https://www.acmicpc.net/problem/2309) 풀고 있었습니다.
아홉명의 난쟁이들의 키가 주어지고 합계가 100인 일곱난쟁이들의 키를 출력하면 되는 문제입니다.
문제의 조건 중 합계가 100인 케이스가 여러개 있어도 그 중에 하나만 출력하면 된다고 주어졌습니다.
강의에서 배웠던 완전탐색의 소스로 문제에 접근하니 합계가 100인 케이스를 전부 다 구했습니다.
조건에 맞게 하나의 케이스만 출력하고 싶은데 방법이 떠오르지 않아 질문 드립니다.

  1. 저는 종료하기 위해서 System.exit(0); 을 사용했는데 코딩테스트에서 사용해도 되는 방법인가요?

  2. 합계가 100인 케이스를 하나 찾으면 완전탐색을 종료하는 방법이 제가 사용한 방법 말고 더 좋은 방법이 있을까요?

Inner class인 FastReader class에 대한 질문

안녕히세요 강사님! 강의 너무 잘 들으며 도움 많이 받고 있습니다. 감사합니다!

다름 아니라, 강사님의 코드에서 FastReader 클래스를 내부 클래스(정적 멤버 클래스)로 구현하여, 데이터를 입력 받을 때 사용하고 계십니다.
이게 static class로 구현하신 점은 Effective Java 책을 통해서 이해를 했는데, 해당 FastReader에 구현된 멤버 필드와 메서드(bufferedReader, stringTokenizer, next(), nextInt() 등..)는 static으로 구현하지 않으신 이유가 궁금합니다.
(모두 static으로 선언해도 풀리긴 하더라구요..! 성능이나 다른 문제가 있을 수 있어서 인지 너무 궁금합니다!)

어떻게 보면 문제에 대한 질문일 수도, 단순 Java 기본에 대한 내용인 질문일 수도 있을 것 같습니다만, 부족한 제게 가르침을 주신다면 너무 감사할 것 같습니다!

항상 감사합니다. 좋은 하루 되세요 :)

BOJ 16472

강사님 안녕하십니까
두 포인터 응용에서 16472 고냥이 문제 질문드리고 싶습니다.
수업을 듣기 전에 제가 풀었는데 수업을 듣고 나서도 제 코드에 대한 반례가 떠오르지 않아 질문 드립니다.

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

public class Main {
    static int N;
    static char ch[];
    static int possible[] = new int[26];
    //값이 0 이면 단어가 없는거고 1 이상이면 있는거
    //boolean 으로 하면 안됨 -> 왜 ? -> b가 여러개 있을수도
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        N = Integer.parseInt(br.readLine());
        String str = br.readLine();

        ch = new char[str.length() + 1];

        for (int i = 0; i < str.length(); i++) {
            ch[i + 1] = str.charAt(i);
        }

        pro();
    }

    static void pro() {
        int e = 0, len = 0, cnt = 0;

        for (int s = 1; s < ch.length; s++) {
            if(s >= 2 && possible[ch[s-1] - 'a'] > 0){
                possible[ch[s-1] - 'a']--;
                if(possible[ch[s - 1] - 'a'] == 0) cnt--;
                //해당 알파벳의 개수가 0이되야 cnt를 뺄 수 있음.
            }

            while(e+1<ch.length && cnt < N){
                if(possible[ch[++e] - 'a'] == 0){
                    cnt++;
                    possible[ch[e] - 'a']++;
                }
                //N이 cnt와 같은 순간에 끝냄

            }

            //N이 같을 때, 뒤 알파벳의 개수가 > 0인 경우는 e를 늘려도 됨됨
            whle (e + 1 < ch.length && possible[ch[e+1] - 'a'] > 0) {
                ++e;
                possible[ch[e] - 'a']++;
            }

            len = Math.max(len, e - s + 1);
//            System.out.println(s + " " + e);
        }

        System.out.println(len);
    }
}

`

제가 해본 경우는
2 ababcc
answer : 4

5 zzzzz
answer : 5

2 aaaaa
answer : 5

2 xyyyz
answer : 4

2 baccab
answer : 4

그리고 게시판에서 반례를 찾아보려고 했으나 해당 문제 반례는 없더라구요
그래서 반례 부탁드립니다.. 혹은 어디 부분이 잘못됐을것이다 힌트 주시면 감사하겠습니다..

트리파트부터 연습문제 코드

안녕하세요. 강사님 강의 수강중인 수강생입니다.

다름이 아니라 트리파트부터 마지막 파트까지 연습문제에 대한 답 코드가 업로드가 안되어 있는데 업로드 해주실수 있는지 문의드립니다.

구글링해서 다른 코드들 참고할 수 있기도 한데 강사님 코드가 강의 토대로한 코드이기도하고 깔끔해서 도움이 많이 되어서요..

제가 java와 python을 같이 보고있기 때문에 혹시 업로드 해주신다면 python 코드도 포함해서 부탁드리겠습니다!

문제 풀이 질문드립니다!

안녕하세요? 현재 삼성 코테를 앞두고 있어, 다양한 시뮬레이션 문제를 풀어보고 있습니다.
그 중 강의에서 배웠던 완전 탐색 파트와 그래프 파트가 적절히 섞인 시뮬레이션 문제를 풀어보면서
혹시 잘못된 부분(ex: 시간복잡도)이나 리팩토링이 필요한 부분이 있는지 알아보기 위해 Issues에 글을 남기게 됐습니다.
문제 설명과 소스코드는 아래와 같습니다.

백준 - 로봇 청소기

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

오늘은 직사각형 모양의 방을 로봇 청소기를 이용해 청소하려고 한다. 이 로봇 청소기는 유저가 직접 경로를 설정할 수 있다.

방은 크기가 1×1인 정사각형 칸으로 나누어져 있으며, 로봇 청소기의 크기도 1×1이다. 칸은 깨끗한 칸과 더러운 칸으로 나누어져 있으며, 로봇 청소기는 더러운 칸을 방문해서 깨끗한 칸으로 바꿀 수 있다.

일부 칸에는 가구가 놓여져 있고, 가구의 크기도 1×1이다. 로봇 청소기는 가구가 놓여진 칸으로 이동할 수 없다.

로봇은 한 번 움직일 때, 인접한 칸으로 이동할 수 있다. 또, 로봇은 같은 칸을 여러 번 방문할 수 있다.

방의 정보가 주어졌을 때, 더러운 칸을 모두 깨끗한 칸으로 만드는데 필요한 이동 횟수의 최솟값을 구하는 프로그램을 작성하시오.

각각의 테스트 케이스마다 더러운 칸을 모두 깨끗한 칸으로 바꾸는 이동 횟수의 최솟값을 한 줄에 하나씩 출력한다. 만약, 방문할 수 없는 더러운 칸이 존재하는 경우에는 -1을 출력한다.

예제 입력 1

7 5
.......
.o...*.
.......
.*...*.
.......
15 13
.......x.......
...o...x....*..
.......x.......
.......x.......
.......x.......
...............
xxxxx.....xxxxx
...............
.......x.......
.......x.......
.......x.......
..*....x....*..
.......x.......
10 10
..........
..o.......
..........
..........
..........
.....xxxxx
.....x....
.....x.*..
.....x....
.....x....
0 0

예제 출력 1

8
49
-1

메모리 : 312872 kb, 시간 : 1264 ms

구현 방법

  • 문자 격자형 그래프를 정수 격자형 그래프로 변환하는 과정을 거쳤습니다.
  • 이를 통해 시작점을 1로, 먼지를 숫자로 표현하여 그래프로 만들었습니다.
  • 따라서 정점과 간선을 구현할 수 있는 graph 배열을 bfs 탐색을 통해 계산해줬습니다.
  • 시간 복잡도는 모든 칸이 먼지일 경우 (N * N)!, BFS N^2
    • O((N^2)! + N^2)...? N이 20

소스 코드 설명

변수 설명

  • Test 클래스를 생성하여 각 testcase에서 정답을 계산할 수 있도록 했습니다.
class Test {
    int y, x, clean, board[][]; // y축 크기, x축 크기, 먼지의 수, 격자
}
ArrayList<Test> tc; // 테스트케이스가 담긴 리스트
  • 각 tc마다 시작점에서 먼지로의 이동가능한 모든 경우의 수를 담는 변수입니다.
ArrayList<ArrayList<Integer>> order; // t.board 격자에서 이동가능한 모든 경우의 수
int number[], select[]; // number배열에 시작점+먼지수만큼 초기화 한 뒤, select에서 모든 경우를 구하고 order에 추가
boolean check[]; // number와 select 계산 과정에서의 중복확인용 배열
  • 2차원 배열 graph를 통해 order에서 갈 수 있는 최소를 찾습니다.
int graph[][]; // bfs를 활용하여 시작점과 먼지의 최단 경로를 구함

함수 설명

solve() 함수
  • 모든 케이스에 대한 정답을 계산하는 함수
  • 케이스마다 preprocess 함수를 통해 order 변수가 초기화 됩니다.
  • 케이스마다 setGraph 함수를 통해 graph 변수가 초기화되고, bfs 함수를 통해 각 정점별 거리가 갱신됩니다.
  • 케이스마다 simulate 함수를 통해 graph 변수를 활용하여, 정답을 구합니다.
preprocess() 함수
  • order 변수를 생성합니다.
  • 먼지의 수(Test객체의 clean값)+1 만큼 number와 select, check를 생성해줍니다.
  • number에 먼지의 수 + 1만큼 순서대로 채워넣고, select 1번 인덱스에는 1을 고정해줍니다.
  • 1번은 시작점, 2 이상 먼지, -1 벽, 0 빈칸
  • 강의에서 배운 rec_func를 2부터 호출하여 N과 M 문제를 풉니다.
void rec_func(int depth, int end) { // n과 m 문제
	if(depth==end) {
		ArrayList<Integer> list = new ArrayList<>(); // order에 넣을 리스트 생성
		for(int i=1; i<end; i++)
			list.add(select[i]);
		order.add(list); // order에 추가
		return;
	} else {
		for(int i=2; i<end; i++) {
			if(!check[i]) {
				check[i] = true;
				select[depth] = i; 
				rec_func(depth+1, end);
				select[depth] = 0;
				check[i] = false;
			}
		}
	}
}
setGraph 함수
  • 먼지의 수 + 1만큼 graph를 생성 후, 초기값을 -1로 설정합니다.
  • 배열 전체를 돌며, 현재 격자가 1 이상, 먼지수 미만이라면
  • loop k (1번부터 먼지수)를 각각 현재격자(from), k(to)로 정한 뒤, bfs 함수를 통해 그래프를 채웁니다.
  • from과 k가 같다면 0을 채웁니다.
  • bfs 함수
int bfs(int[][] board, int y, int x, int from, int to) { // from과 to를 이용해 최단거리 계산. 실패의 경우 -1
	Queue<int[]> q = new ArrayDeque<>();
	int row_size = board.length;
	int col_size = board[0].length;
	boolean visit[][] = new boolean[row_size][col_size];
	int dir[][] = { {0,1},{0,-1},{1,0},{-1,0}};
	q.add(new int[] {y, x, 0});
	visit[y][x] = true;
	while(!q.isEmpty()) {
		int info[] = q.poll();
		int cy = info[0];
		int cx = info[1];
		int dis = info[2];
		if(board[cy][cx]==to) {
			return dis;
		} else {
			for(int d=0; d<4; d++) {
				int ny = cy + dir[d][0];
				int nx = cx + dir[d][1];
				if(nx<0 || ny<0 || nx>=col_size || ny>=row_size)
					continue;
				if(visit[ny][nx])
					continue;
				if(board[ny][nx]==-1)
					continue;
				q.add(new int[] {ny, nx, dis+1});
				visit[ny][nx] = true;
			}
		}
	}
	return -1;
}

BOJ 11057 오르막 수 문제 - by zero 런타임에러가 납니다.

강의 내용과 다르게 점화식을 풀었습니다. 길이가 n이고 마지막 수를 last라고 할 때, n-1개의 자리에 0~last까지의 숫자를 중복 조합으로 계산하면 답이 나와서 중복 조합 공식 nHr로 문제를 풀어서 last+1Hn-1 의 공식으로 문제를 풀었습니다. 제가 봤을 땐 코드에 0으로 나누어지는 경우가 없어 보이는데 왜 런타임 에러가 나는지 모르겠습니다ㅠㅠ

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

//오르막 수
public class p11057 {

static int n, ans = 0;
static int[][] dp;

public static void main(String[] args) throws IOException {
    input();
    pro();

    System.out.println(ans);
}

static void input() throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    n = Integer.parseInt(br.readLine());

    dp = new int[n + 1][10];
}

static void pro() {

    // n=1인 경우
    for (int last = 1; last <= 9; last++) {
        dp[1][last] = 1;
    }
    // 뒤가 0으로 끝나는 경우
    for (int len = 1; len <= n; len++) {
        dp[len][0] = 1;
    }

    if (n > 1) {
        for (int len = 2; len <= n; len++) {
            for (int last = 1; last <= 9; last++) {
                int tmpans = fac(last + len - 1) / fac(last) / fac(len - 1);
                dp[len][last] = tmpans % 10007;
            }
        }
    }

    for (int i = 0; i <= 9; i++) {
        ans += dp[n][i];
    }

}

static int fac(int k) {
    if (k == 1) {
        return 1;
    }
    return k * fac(k - 1);
}

}

BOJ 9084 동전

문제 : (https://www.acmicpc.net/problem/9084)

강사님 안녕하십니까 오랜만에 질문 드립니다..
제가 강사님 방법대로 dp를 풀고 있는데 마지막 풀이에서 막히게 됐습니다.
구글링을 해서 모든 블로그를 다 봤지만 이렇게 파티셔닝을 하고 점화식을 도출해내는 곳은 강사님 밖에 안 계신 것 같습니다..
그래서 바쁘시겠지만 염치 불구하고 강의에 없는 문제에 도움 요청해봅니다..
혹시 강의 외 코드에 관해 질문을 받지 않으신다면 다음부터 하지 않도록 하겠습니다!

  1. 가짜 문제 정의
    예제의 케이스는 너무 커서 2, 3, 5원의 동전을 가지고 10원을 만들어보자.

  2. dp[i]는 i원을 만들 수 있는 방법의 개수를 의미함. 따라서 dp[10]을 하면 답을 구할 수 있을 것 같다.

  3. d[0] = 1
    왜 ?
    d[5] = d[2] + d[3] + d[0] 인데 이 때 값을 만족하기 위해서는 d[0] = 1이어야함. 그리고 0원짜리 동전이 있다고 생각

  4. 점화식 구해내기 ( 파티셔닝 )

처음에 파티셔닝을 할 때에는 중복을 고려하고 작성했습니다.
예를 들어, 5원을 만들 수 있는 경우의 수 중에 2 + 3, 3 + 2가 있는데 중복을 고려하여 2 + 3만 적을 경우 파티셔닝이 잘 되지 않아 중복을 고려하지 않고 파티셔닝을 진행했습니다.
(옛날에 강사님께 배웠었습니다.)

파티셔닝을 하기 위해 모든 경우의 수를 작성해보았습니다. ( 파란색은 중복을 고려했을 경우)

image

그래서 d[10] = d[10 - 2] + d[10 - 3] + d[10 - 5] 와 같이 규칙성을 알아내어 점화식을 구했습니다.

점화식 : d[i] = d[i - coin[j]] 입니다.

image

점화식은 맞았는데 for문 구현하지 못했습니다.

제가 저를 납득시켜야 문제를 이해했다고 생각하는데.. 제가 작성한 점화식을 구하는 과정에서 위와 같은 답을 어떻게 도출해낼 수 있을까요??

저는 d[i - coin[j]] 가 음수가 나오지 않기 위해 이렇게 사용한다 라고 생각은 하지만 뭔가 와닿지가 않아서 여쭤보고 싶습니다..

감사합니다

BOJ 2470

선생님 안녕하십니까 이분 탐색 강의 중에 두 용액 문제에 대해 궁금한 점이 생겨 질문드립니다.

문제 설명 중에 A[Left]를 정했을 때, -A[Left]랑 가장 가까운 걸 빨리 찾아 이 부분에서
어디서? A[(Left+1) ~ N] 까지 라고 말씀하셨습니다.

lower_bound는 A[left]와 더한 값이 0에 가장 가까운 수의 index를 구하기 위한 것이라고 생각합니다.
그런데 이렇게 할 수 있는 근거가 궁금합니다.
제가 L이 4일 때 넣어보면

lowerbound(A, 5, 5, -4)

  1. mid = 5
    A[5] >= -4
    res = 5
    R = 4
    while문 끝

그렇다면 -4와 가장 가까운 것은 98 또는 4 중에 되는걸까요?

아니면 아래의 if문에서 걸러지기 떄문에 상관이 없는지 궁금합니다.

boj1654 랜선자르기 long

랜선 길이가 2^31-1까지로 int 범위에 해당되어서 이분 탐색할 때 r의 타입을 int로 하였는데 답안을 확인해보니 타입이 long이더라구요. 왜 long인지 이유를 모르겠어요....

연습 문제 중 배열 합치기

강사님 안녕하십니까 이번엔 두 포인터 강의 듣고있습니다.
기본 문제를 풀면서 문제를 맞더라도 강사님 코드를 한 번 더 보고 익히는데,
두 포인터에서 배열 합치기 문제의 코드가 부분합 코드와 매우 유사해보여 질문드립니다.

혹시 맞다면 강사님의 배열 합치기 코드를 보고싶습니다.

완전 탐색, 백트래킹 문제가 잘 안풀립니다

안녕하세요 류호석님
저는 강의를 너무 잘 듣고 있는 한 수강생입니다. 좋은 강의 정말로 감사합니다!!!

일단 문제 개념 강의는 한바퀴는 돌고 문제도 한번씩 본상태입니다
근데 저는 다른 알고리즘보다... 완전탐색, 백트래킹 문제는 도저히 잘 안풀립니다...
강의도 듣고 연습문제도 풀어보고 있는데 강의에 없는 문제를 막상 혼자 풀려고하면 잘 안풀리네요...

혹시 무엇을 좀더 공부해야 잘 할 수 있을까요??
재귀를 좀더 공부해야할까요...? 아니면 계속 완전 탐색 문제를 풀어봐야할까요...? 너무 어렵습니다
혹시 문제를 좀더 선별해 주실 수 도 있으신가요??

류호석님의 완전 탐색 베이스 코드를 기반으로 제가 문제를 풀고있는데 문제에 맞춰 제가 변형하는것을 잘 못하는거 같습니다...
어떤 팁이라도 주시면 감사하겠습니다 ㅜㅜ

실제 문제 푸실때도 스케치 진행 여부 질문

안녕하십니까 류호석님
패캠 java369 수강생입니다

고퀄리티의 강의를 찍어주셔서 감사합니다

류호석님의 문제 해설 강의를 볼때 항상 구현할 함수에 주석으로 스케치를 하신것을 많이 볼 수 있었습니다
이것이 강의를 찍기위해서가 아니라 류호석님도 실제로 구현시 그렇게 스케치를 진행하고 문제를 푸시나요??
문제풀기전에 솔루션 접근 방법이나 시간 복잡도와 공간 복잡도를 계산하는 정도까지는 알겠는데 주석으로 스케치까지 실제로 진행하시는지가 궁금합니다

dp 2579 계단 오르기

안녕하십니까 선생님
dp 계단 오르기 문제를 풀다가 질문 드립니다,,

푸실 때, dp size를 N+1만큼 해주셨는데 저는 N만큼해서 풀어보고 싶었습니다.
그래서 아래와 같이 풀었는데 런타임 에러가 나더군요.

N+1만큼 하는 것은 이해가 갔습니다. 그러나 문제에서 어차피 시작점은 계단에 포함되지 않아서 N크기만큼 할당해도 되지 않을까라는 생각이 들었습니다.

왜 N크기만큼 하면 런타임 에러가 뜨는지 궁금합니다,,

아래는 런타임 에러가 나온 코드입니다.

import java.io.*;

public class Main{
    static int atoi(String str) {
        return Integer.parseInt(str);
    }
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int size = atoi(br.readLine());
        int arr[] = new int[size];

        for (int i = 0; i < size; i++) {
            arr[i] = atoi(br.readLine());
        }

        int dp[][] = new int[size][2];

        dp[0][0] = 0;
        dp[0][1] = arr[0];

        if (size >= 1) {
            dp[1][0] = arr[1];
            dp[1][1] = arr[0] + arr[1];
        }

        for (int i = 2; i < size; i++) {
            dp[i][0] = Math.max(dp[i - 2][0], dp[i - 2][1]) + arr[i];
            dp[i][1] = dp[i - 1][0] + arr[i];
        }

        System.out.println(Math.max(dp[size-1][0], dp[size-1][1]));
    }
}

백준 2512번 - 예산 (이분탐색) 질문드립니다!

안녕하세요! 문제를 풀다 질문이 생겨서 글 남깁니다.

이 문제에서 r의 초기값이 배열 A의 최댓값으로 주어지는데, 그 이유가 출력되는 ans의 값이 A의 최댓값을 넘기지 않기 때문인가요?
다른 큰 값(10억, m)으로 설정했을 때에는 틀려서 질문드립니다.

항상 강의 잘 듣고있습니다! 감사합니다.

dp 15991번 1 2 3 더하기 6

image

안녕하십니까 선생님 dp 첫 번째 강의를 듣고 풀어보라고 하시는 문제 중에 1 2 3 더하기 6을 풀다가 질문이 있어 여쭤봅니다.
질문 전에 구글링을 한 뒤, 블로그들의 풀이를 보았지만 와닿는 풀이가 없어 선생님께서는 어떻게 접근하셨을까 궁금해서 이슈 올립니다.
문제는 이렇게 시도해보았습니다.
KakaoTalk_20210709_033011614 png
하지만 i 가 6일 때는 d[0] 값이 필요한데, d[0]은 원래는 0이지 않습니까?? 1 2 3으로 구성되어야하니까요.

물론 포문을 i가 7부터 시작하여 dp[0]을 포함하지 않으면서 풀 수 있지만, 위와 같이 문제를 해결해도 되는지, 올바른 접근 방법인지 궁금합니다. 이 문제에 대해서 설명해보라하면 설명을 하지 못할 것 같아 이렇게 질문을 드립니다..

읽어주셔서 감사합니다.

BOJ1637 날카로운 눈 질문드립니다

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

public class BOJ1637 {
    static StringBuilder sb = new StringBuilder();
    static FastReader scan = new FastReader();

    static int N, maxint, ans, total;
    static int[] A,B,C;

    static void input() {
        N = scan.nextInt();
        maxint = Integer.MIN_VALUE;
        A = new int[N];
        B = new int[N];
        C = new int[N];
        for (int i = 0; i < N; i++){
            A[i] = scan.nextInt();
            B[i] = scan.nextInt();
            C[i] = scan.nextInt();
            maxint = Math.max(maxint,B[i]);
        }
    }

    static void pro() {
        int left = 1;
        int right = maxint;
        boolean noodd = true;
        while (right >= left) {
            int mid = (left + right) / 2;
            int cnt = 0;
            for (int i = 0; i < N; i++) {
                if(A[i] > mid) continue;
                if (B[i] >= mid) cnt += (mid - A[i]) / C[i];
                else cnt += (B[i] - A[i]) / C[i] + 1;

            }
            if (cnt % 2 == 0) {
                ans = mid;
                left = mid + 1;
            }
            
            else {
                right = mid - 1;
                noodd = false;
            }
        }

        if (noodd) sb.append("NOTHING");
        else{
            for (int i = 0; i < N; i++) {
                if ((ans <= B[i] && ans >= A[i]) && ((ans - A[i]) % C[i] == 0)) total++;
            }
            sb.append(ans).append(' ').append(total);
        }
    }
    
    public static void main(String[] args) {
        input();
        pro();
        System.out.println(sb);
    }


    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws FileNotFoundException {
            br = new BufferedReader(new FileReader(new File(s)));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}

우선 컴파일 해서 테스트 케이스 정답과 일치하는지 확인하고 제출 하였습니다. 그런데 시간초과로 실패하게 되었는데, 제가 생각한 시간복잡도는 홀수인 정수를 찾는 과정에서 이분탐색으로 Nlog(N), 그리고 정수의 갯수를 구하는 과정에서 N으로 계산된다고 생각했는데 제가 잘못 판단하고 있는 부분이 있을까요?, 솔루션으로 올려주신 파일과도 논리적으로 크게 다를게 없다고 판단하는데... 문제점 지적해주시면 감사하겠습니다

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.