www.acmicpc.net/problem/9372

 

9372번: 상근이의 여행

첫 번째 줄에는 테스트 케이스의 수 T(T ≤ 100)가 주어지고, 각 테스트 케이스마다 다음과 같은 정보가 주어진다. 첫 번째 줄에는 국가의 수 N(2 ≤ N ≤ 1 000)과 비행기의 종류 M(1 ≤ M ≤ 10 000) 가

www.acmicpc.net

이문제는 모든 국가를 여행하는데 타야하는 비행기의 최소 갯수를 출력하는 문제입니다.

입력으로는 무조건 연결그래프만 주어지며, N개의 국가를 모두 연결하기 위해서는 최소 N - 1개의 간선만 있으면 됩니다.

입력만 다받고 N - 1를 출력해줍시다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package BOJ.data_structure;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Boj9372 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static int N;
 
    static void input() throws Exception {
        int M, x;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        while (M-- > 0) {
            st = new StringTokenizer(br.readLine());
            x = Integer.parseInt(st.nextToken());
            x = Integer.parseInt(st.nextToken());
        }
 
        sb.append(N - 1 + "\n");
    }
 
    public static void main(String[] args) throws Exception {
        st = new StringTokenizer(br.readLine());
        int tc = Integer.parseInt(st.nextToken());
        while (tc-- > 0) {
            input();
        }
        
        System.out.println(sb.toString());
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 21939 문제 추천 시스템 Version 1  (0) 2022.02.11
boj 17299 오등큰수  (0) 2021.02.22
boj 1158 요세푸스 문제  (0) 2021.02.09
boj 1918 후위 표기식  (0) 2021.02.05
boj 1935 후위 표기식2  (0) 2021.02.05

www.acmicpc.net/problem/1158

 

1158번: 요세푸스 문제

첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000)

www.acmicpc.net

1 ~ N 까지 순서대로 저장되어있으면 매번 K번째 수를 제거하고, 제거되는 숫자 순서대로 출력하는 문제입니다.

 

저는 덱을 이용하여 1 ~ N 까지의 숫자를 넣었고, K번째 수를 제거하기 위해 1 ~ K - 1번째 수를 뒤로 보낸 후에 제거하였습니다.

 

원래 큐를 이용하는 문제지만 저는 덱이 먼저 떠올라서 덱으로 풀었습니다.

하지만 이유는 모르겠으나 메모리와 시간 차이가 있었습니다.

Queue를 이용한 풀이

 

Deque를 이용한 풀이

무슨 이유일까요... 소스 두개모두 올립니다...

아마 ArrayDeque와 LinkedList의 차이인것 같습니다..

LinkedList가 좌 우를 연결하는 link를 다루기때문에 이에대한 추가 메모리 발생과 link 연결을 위한 연산시간이 추가로 발생하는게 아닌가하는 생각이 듭니다.

 

 

[Queue]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static Queue<Integer> q = new LinkedList<>();
    static int N, K;
 
    static void func() {
        sb.append("<");
        while (!q.isEmpty()) {
            for (int i = 0; i < K - 1; i++) {
                q.add(q.poll());
            }
 
            sb.append(q.poll());
            if (!q.isEmpty())
                sb.append(", ");
        }
        sb.append(">");
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
 
        for (int i = 1; i <= N; i++)
            q.add(i);
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

 

 

[Deque]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static Deque<Integer> dq = new ArrayDeque<>();
    static int N, K;
 
    static void func() {
        sb.append("<");
        while (!dq.isEmpty()) {
            for (int i = 0; i < K - 1; i++) {
                dq.addLast(dq.pollFirst());
            }
 
            sb.append(dq.pollFirst());
            if (!dq.isEmpty())
                sb.append(", ");
        }
        sb.append(">");
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
 
        for (int i = 1; i <= N; i++)
            dq.addLast(i);
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 17299 오등큰수  (0) 2021.02.22
boj 9372 상근이의 여행  (0) 2021.02.09
boj 1918 후위 표기식  (0) 2021.02.05
boj 1935 후위 표기식2  (0) 2021.02.05
boj 2493 탑  (0) 2021.02.04

www.acmicpc.net/problem/10826

 

10826번: 피보나치 수 4

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다. 이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가

www.acmicpc.net

 

점화식 : dp[i] = dp[i - 1] + dp[i - 2]

앞의 두 개의 수를 더한 값이 자신의 값이 됩니다.

 

이 문제는 N이 10000까지 오기때문에 long의 범위를 초과합니다.

자바에는 BigInteger라는 클래스가 있기때문에 이용 사용하여 쉽게 구할 수 있습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int N;
 
    static void solve() {
        BigInteger dp[] = new BigInteger[10001];
        dp[0= new BigInteger("0");
        dp[1= new BigInteger("1");
        for (int i = 2; i <= N; i++) {
            dp[i] = dp[i - 1].add(dp[i - 2]);
        }
 
        System.out.println(dp[N]);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
    }
 
    public static void main(String[] args) throws Exception {
        input();
        solve();
    }
}
cs

'algorithm > dp' 카테고리의 다른 글

boj 1912 연속합  (0) 2021.02.18
boj 10211 Maximum Subarray  (0) 2021.02.18
boj 5569 출근 경로  (0) 2021.02.06
boj 1010 다리 놓기  (0) 2021.02.05
boj 5557 1학년  (0) 2021.02.05

www.acmicpc.net/problem/20304

 

20304번: 비밀번호 제작

서강대학교 전산실에서 보안직원으로 일하는 향빈이는 한 통의 이메일을 받게 되었다. 이메일에는 서버 관리자 계정에 대한 비정상적인 로그인 시도가 감지되었다는 내용이 적혀 있었고, 첨부

www.acmicpc.net

bfs에 비트마스킹까지 해야하는 문제입니다.

 

관리자 계정 비밀번호와 해커가 로그인 시도에 사용된 비밀번호의 안전거리로 계산한 안전도를 최대로 해야합니다.

우선 로그인 시도에 사용된 비밀번호가 관리자 계정 비밀번호와 같으면 안전거리는 0입니다. (고정)

이를 큐에 넣고 비트마스킹을 이용하여 bfs로 탐색을 합니다. 큐에는 번호와 안전도를 유지합니다.

 

이제 1부터 왼쪽시프트를 하면서 x와 &연산을 합니다. (y = x & i)

y > 0이면 같은 자릿수가 있다는 의미이며, x - i를 한 값이 거리가 1인 숫자입니다.

그리고 y == 0이면 같은 자릿수가 없다는 의미이며, x + i를 한 값이 거리가 1인 숫자입니다.

 

이 과정을 반복하여 cnt의 max를 구하여 출력합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static Queue<int[]> q = new LinkedList<>();
    static int visit[];
    static int N, M, ans;
 
    static void bfs() {
        while (!q.isEmpty()) {
            int x = q.peek()[0];
            int cnt = q.poll()[1];
 
            ans = Math.max(ans, cnt);
            for (int i = 1; i <= N; i = i << 1) {
                int y = x & i;
 
                if (y > 0) {
                    if (visit[x - i] != -1)
                        continue;
                    q.add(new int[] { x - i, cnt + 1 });
                    visit[x - i] = cnt + 1;
                } else {
                    if (x + i > N || visit[x + i] != -1)
                        continue;
                    q.add(new int[] { x + i, cnt + 1 });
                    visit[x + i] = cnt + 1;
                }
            }
        }
 
        System.out.println(ans);
    }
 
    static void input() throws Exception {
        int x;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        visit = new int[N + 1];
        Arrays.fill(visit, -1);
 
        st = new StringTokenizer(br.readLine());
        M = Integer.parseInt(st.nextToken());
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < M; i++) {
            x = Integer.parseInt(st.nextToken());
            q.add(new int[] { x, 0 });
            visit[x] = 0;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        bfs();
    }
}
cs

'algorithm > bfs' 카테고리의 다른 글

boj 2206 벽 부수고 이동하기  (0) 2021.02.13
boj 14502 연구소  (0) 2021.02.12
boj 2606 바이러스  (0) 2021.02.03
boj 1012 유기농 배추  (0) 2021.02.03
boj 16956 늑대와 양  (0) 2021.02.03

www.acmicpc.net/problem/1914

 

1914번: 하노이 탑

세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이 다음 규칙에 따라 첫 번째 장대에서 세 번째 장대로

www.acmicpc.net

emoney96.tistory.com/102

 

boj 11729 하노이 탑 이동 순서

www.acmicpc.net/problem/11729 11729번: 하노이 탑 이동 순서 세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이

emoney96.tistory.com

이 문제랑 같은 문제입니다.

이동 순서는 위의 문제와 동일하게 해주시면 됩니다.

 

하나 다른점은 N이 최대 100이며, N>20인 경우에는 횟수만 출력합니다.

2^100 - 1 = 1267650600228229401496703205375 이므로 long의 범위도 초과합니다.

그래서 자바의 BigInteger를 사용합니다.

BigInteger에 pow라는 지수메소드가 있어서 2^N을 구할 수 있고, subtract 메소드로 1을 감소시켜줍니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static BigInteger ans = new BigInteger("2");
    static int N;
 
    static void func(int n, int a, int b, int c) {
        if (n < 1)
            return;
 
        func(n - 1, a, c, b);
        sb.append(a + " " + c + "\n");
        func(n - 1, b, a, c);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
 
        ans = ans.pow(N).subtract(new BigInteger("1"));
    }
 
    public static void main(String[] args) throws Exception {
        input();
        System.out.println(ans);
        if (N > 20) {
            return;
        }
        func(N, 123);
        System.out.println(sb.toString());
    }
}
cs

'algorithm > Implementation' 카테고리의 다른 글

boj 16918 봄버맨  (0) 2021.02.17
boj 16935 배열 돌리기 3  (0) 2021.02.10
boj 11729 하노이 탑 이동 순서  (0) 2021.02.07
boj 1244 스위치 켜고 끄기  (0) 2021.02.01
boj 20127 Y-수열  (0) 2021.01.22

www.acmicpc.net/problem/11729

 

11729번: 하노이 탑 이동 순서

세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이 다음 규칙에 따라 첫 번째 장대에서 세 번째 장대로

www.acmicpc.net

하노이탑 이동 횟수와 순서를 출력하는 문제입니다.

 

하노이탑은 3개의 기둥이 있고, 한 기둥에 원판들이 작은 것이 위에 있고 순서대로 밑으로 쌓여있습니다.

한 번에 하나의 원판만 옮길 수 있고, 큰 원판이 작은 원판 위에 있으면 안됩니다.

 

일단 원판이 n개 일 때, 이동 횟수는 2^n - 1개입니다.

비트연산을 이용하면 빠르게 구할 수 있습니다.

 

그리고, 재귀를 통해 순서를 출력해주시면 됩니다.

저는 "func(n, a, b, c) : n개의 원판이 a에서 c로 이동하는 경우" 이렇게 함수를 선언하였습니다.

그 다음 n - 1개를 a에서 b로 옮기고, 나머지 1개를 a에서 c로 옮기고, n - 1개를 b에서 c를 옮기는 로직입니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static int N;
 
    static void func(int n, int a, int b, int c) {
        if (n < 1)
            return;
        func(n - 1, a, c, b);
        sb.append(a + " " + c + "\n");
        func(n - 1, b, a, c);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
 
        sb.append((2 << (N - 1)) - 1 + "\n");
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(N, 123);
        System.out.println(sb.toString());
    }
}
cs

'algorithm > Implementation' 카테고리의 다른 글

boj 16918 봄버맨  (0) 2021.02.17
boj 16935 배열 돌리기 3  (0) 2021.02.10
boj 1914 하노이 탑  (0) 2021.02.07
boj 1244 스위치 켜고 끄기  (0) 2021.02.01
boj 20127 Y-수열  (0) 2021.01.22

www.acmicpc.net/problem/2252

 

2252번: 줄 세우기

첫째 줄에 N(1≤N≤32,000), M(1≤M≤100,000)이 주어진다. M은 키를 비교한 회수이다. 다음 M개의 줄에는 키를 비교한 두 학생의 번호 A, B가 주어진다. 이는 학생 A가 학생 B의 앞에 서야 한다는 의미이

www.acmicpc.net

자신보다 뒤에 서야하는 학생의 번호를 list에 넣습니다.

그리고 뒤에 서야하는 학생의 번호는 conn 배열을 이용하여 자신보다 앞에 서야하는 학생이 몇명인지 유지합니다.

 

그 다음 conn[i]이 0인 학생들의 번호만 큐에 추가한 후에 bfs를 돌립니다.

 

먼저 번호 x보다 뒤에 서야하는 번호를 하나씩 확인하여 conn[y]--를 해줍니다.

conn[y]=0이 되면 자신보다 앞에 있어야할 번호를 모두 탐색을 했으므로 y를 큐에 추가합니다.

이런 방식으로 ans에 번호를 차례대로 쌓는 방식입니다.

 

이 문제는 줄을 못 세우는 경우가 없기 때문에 ans의 크기가 N보다 작은지 확인하는 예외처리를 하지 않았습니다.

만약 문제에서 이런 경우는 요구하면 무조건 해줘야하는 예외케이스 입니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static ArrayList<Integer> list[] = new ArrayList[32001];
    static ArrayList<Integer> ans = new ArrayList<>();
    static int conn[] = new int[32001];
    static int N, M;
 
    static void print() {
        for (int i = 0; i < ans.size(); i++) {
            sb.append(ans.get(i) + " ");
        }
        System.out.println(sb.toString());
    }
 
    static void func() {
        Queue<Integer> q = new LinkedList<>();
        for (int i = 1; i <= N; i++) {
            if (conn[i] == 0) {
                q.add(i);
            }
        }
 
        while (!q.isEmpty()) {
            int x = q.poll();
 
            ans.add(x);
            for (int i = 0; i < list[x].size(); i++) {
                int y = list[x].get(i);
 
                conn[y]--;
 
                if (conn[y] == 0)
                    q.add(y);
            }
        }
    }
 
    static void input() throws Exception {
        int u, v;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        for (int i = 1; i <= N; i++)
            list[i] = new ArrayList<>();
 
        while (M-- > 0) {
            st = new StringTokenizer(br.readLine());
            u = Integer.parseInt(st.nextToken());
            v = Integer.parseInt(st.nextToken());
            list[u].add(v);
            conn[v]++;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

'algorithm > Topological-sort' 카테고리의 다른 글

boj 23059 리그 오브 레게노  (0) 2021.12.15

www.acmicpc.net/problem/1717

 

1717번: 집합의 표현

첫째 줄에 n(1 ≤ n ≤ 1,000,000), m(1 ≤ m ≤ 100,000)이 주어진다. m은 입력으로 주어지는 연산의 개수이다. 다음 m개의 줄에는 각각의 연산이 주어진다. 합집합은 0 a b의 형태로 입력이 주어진다. 이는

www.acmicpc.net

union-find를 사용해볼 수 있는 문제입니다.

 

합집합 연산은 0 a b 형태로 주어지고, a가 포함되어 있는 집합과 b가 포함되어 있는 집합을 합친다는 의미입니다.

두 집합이 같은 집합인지 확인하는 연산은 1 a b 형태로 주어지고, a와 b가 같은 집합이면 YES, 아니면 NO를 출력하는 문제입니다.

 

저는 일단 parent배열에 집합의 루트를 자신으로 저장해놓고, union_find를 통해 a의 루트와 b의 루트를 찾아서

합치거나, 같은 집합인지 확인하였습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int parent[] = new int[1000001];
    static int N, M;
 
    static int find(int v) {
        if (parent[v] == v)
            return v;
        return parent[v] = find(parent[v]);
    }
 
    static void union(int u, int v) {
        int a = find(u);
        int b = find(v);
 
        if (parent[a] != parent[b])
            parent[b] = parent[a];
    }
 
    static void func() throws Exception {
        StringBuffer sb = new StringBuffer();
        int type, u, v;
        while (M-- > 0) {
            st = new StringTokenizer(br.readLine());
            type = Integer.parseInt(st.nextToken());
            u = Integer.parseInt(st.nextToken());
            v = Integer.parseInt(st.nextToken());
 
            if (type == 0)
                union(Math.min(u, v), Math.max(u, v));
            else {
                if (find(u) == find(v))
                    sb.append("YES\n");
                else
                    sb.append("NO\n");
            }
        }
        
        System.out.print(sb.toString());
    }
 
    static void init() {
        for (int i = 1; i <= N; i++) {
            parent[i] = i;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
    }
 
    public static void main(String[] args) throws Exception {
        input();
        init();
        func();
    }
}
cs

'algorithm > Union-Find' 카테고리의 다른 글

boj 20040 사이클 게임  (0) 2021.06.27
boj 1043 거짓말  (0) 2021.04.05
boj 10775 공항  (0) 2021.03.17
boj 4195 친구 네트워크  (0) 2021.03.17
boj 1976 여행 가자  (0) 2021.03.17

www.acmicpc.net/problem/5569

 

5569번: 출근 경로

상근이가 사는 도시는 남북 방향으로 도로가 w개, 동서 방향으로 도로가 h개 있다.  남북 방향 도로는 서쪽부터 순서대로 번호가 1, 2, ..., w로 매겨져 있다. 또, 동서 방향 도로는 남쪽부터 순서대

www.acmicpc.net

저는 4차원배열로 dp를 구성하였습니다.

 

dp[x][y][t][chk]

x, y 좌표

t : 현재 진행방향 (0 -> x / 1 -> y)

chk : 방향 변경 가능 여부 (0 -> 변경 불가능 / 1 -> 변경 가능)

 

현재 진행 방향에서 chk = 0이면 현재 진행방향으로 이동해야합니다.

chk = 1이면 현재 진행방향, 다른 방향 모두 탐색합니다.

 

모든 경우의 수를 계산하여 100000으로 나눈 나머지를 출력합니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static final int MOD = 100000;
    static int dp[][][][];
    static int N, M;
 
    static int func(int x, int y, int t, int chk) {
        if (x <= 0 || y <= 0 || x > N || y > M)
            return 0;
 
        if (x == N && y == M)
            return dp[x][y][t][chk] = 1;
 
        if (dp[x][y][t][chk] != -1)
            return dp[x][y][t][chk];
 
        dp[x][y][t][chk] = 0;
        if (t == 1) {
            if (chk == 1) {
                dp[x][y][t][chk] = (dp[x][y][t][chk] + func(x, y + 1, t, chk) + func(x + 1, y, 1 - t, 1 - chk)) % MOD;
            } else {
                dp[x][y][t][chk] = (dp[x][y][t][chk] + func(x, y + 1, t, 1 - chk)) % MOD;
            }
        } else {
            if (chk == 1) {
                dp[x][y][t][chk] = (dp[x][y][t][chk] + func(x + 1, y, t, chk) + func(x, y + 11 - t, 1 - chk)) % MOD;
            } else {
                dp[x][y][t][chk] = (dp[x][y][t][chk] + func(x + 1, y, t, 1 - chk)) % MOD;
            }
        }
 
        return dp[x][y][t][chk];
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        dp = new int[N + 1][M + 1][2][2];
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++) {
                Arrays.fill(dp[i][j][0], -1);
                Arrays.fill(dp[i][j][1], -1);
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        System.out.println((func(1100+ func(1110)) % MOD);
    }
}
cs

'algorithm > dp' 카테고리의 다른 글

boj 10211 Maximum Subarray  (0) 2021.02.18
boj 10826 피보나치 수 4  (0) 2021.02.08
boj 1010 다리 놓기  (0) 2021.02.05
boj 5557 1학년  (0) 2021.02.05
boj 5573 산책  (0) 2021.02.04

www.acmicpc.net/problem/1010

 

1010번: 다리 놓기

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 강의 서쪽과 동쪽에 있는 사이트의 개수 정수 N, M (0 < N ≤ M < 30)이 주어진다.

www.acmicpc.net

이항계수 공식을 이용하는 문제입니다.

dp[K][N] = kCn으로 하였고, kCn = (k-1)C(n-1)+(k-1)C(n)의 공식을 이용하면 풀리는 문제입니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main{
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static int dp[][] = new int[31][31];
    static int N, M;
 
    static void init() {
        for (int i = 1; i <= 30; i++) {
            dp[i][0= 1;
            dp[0][i] = 1;
        }
 
        for (int i = 1; i <= 30; i++) {
            for (int j = 1; j <= i; j++) {
                dp[i][j] = dp[i - 1][j - 1+ dp[i - 1][j];
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        init();
        st = new StringTokenizer(br.readLine());
        int tc = Integer.parseInt(st.nextToken());
        int N, K;
        while (tc-- > 0) {
            st = new StringTokenizer(br.readLine());
            N = Integer.parseInt(st.nextToken());
            K = Integer.parseInt(st.nextToken());
            sb.append(dp[K][N] + "\n");
        }
 
        System.out.println(sb.toString());
    }
}
cs

'algorithm > dp' 카테고리의 다른 글

boj 10826 피보나치 수 4  (0) 2021.02.08
boj 5569 출근 경로  (0) 2021.02.06
boj 5557 1학년  (0) 2021.02.05
boj 5573 산책  (0) 2021.02.04
boj 17528 Two Machines  (0) 2021.01.28

www.acmicpc.net/problem/1918

 

1918번: 후위 표기식

첫째 줄에 중위 표기식이 주어진다. 단 이 수식의 피연산자는 A~Z의 문자로 이루어지며 수식에서 한 번씩만 등장한다. 그리고 -A+B와 같이 -가 가장 앞에 오거나 AB와 같이 *가 생략되는 등의 수식

www.acmicpc.net

입력은 중위 표기식으로 주어지고 후위 표기식으로 출력하는 문제입니다.

 

우선 A ~ Z까지의 문자는 바로 출력입니다.

'('는 스택에 바로 push하시면 되고

')'가 나오면 스택에 '('가 나올때까지 pop한 것을 출력해줍니다.

+, -가 나오면 자신보다 우선순위가 낮은 연산자가 없으므로 괄호를 만날때까지 pop한 것을 출력해줍니다.

*, /가 나오면 자신보다 우선순위가 낮은 +, -가 나오거나 괄호를 만날때까지 pop한 것을 출력해줍니다.

마지막에 남아있는 연산자를 모두 출력합니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static StringBuffer sb = new StringBuffer();
    static Stack<Character> s = new Stack<>();
    static char ch[];
 
    static void func() {
        for (char x : ch) {
            if ('A' <= x && x <= 'Z')
                sb.append(x);
            else if (x == '(')
                s.push(x);
            else if (x == ')') {
                while (s.peek() != '(')
                    sb.append(s.pop());
                s.pop();
            } else if (x == '+' || x == '-') {
                while (!s.isEmpty() && s.peek() != '(')
                    sb.append(s.pop());
                s.push(x);
            } else {
                while (!s.isEmpty() && (s.peek() == '*' || s.peek() == '/'))
                    sb.append(s.pop());
                s.push(x);
            }
        }
 
        while (!s.isEmpty())
            sb.append(s.pop());
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        ch = st.nextToken().toCharArray();
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 9372 상근이의 여행  (0) 2021.02.09
boj 1158 요세푸스 문제  (0) 2021.02.09
boj 1935 후위 표기식2  (0) 2021.02.05
boj 2493 탑  (0) 2021.02.04
boj 6416 트리인가?  (0) 2021.02.04

www.acmicpc.net/problem/1935

 

1935번: 후위 표기식2

첫째 줄에 피연산자의 개수(1 ≤ N ≤ 26) 가 주어진다. 그리고 둘째 줄에는 후위 표기식이 주어진다. (여기서 피연산자는 A~Z의 영대문자이며, A부터 순서대로 N개의 영대문자만이 사용되며, 길이

www.acmicpc.net

피연산자가 문자로 주어진 후위표기식이 입력으로 들어오면 이를 계산한 결과를 소수 둘째 자리까지 출력하는 문제입니다.

우선 피연산자에 대응하는 값은 alphabet 배열에 넣어서 alphabet[ch-'A']와 같이 사용하였습니다.

 

A ~ Z가 오면 스택에 대응하는 값을 넣고, 연산자가 오면 두개를 꺼내서 계산한 값을 스택에 넣었습니다.

마지막에 스택에 들어있는 값은 1개이므로 그것을 출력하면 됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static Stack<Double> s = new Stack<>();
    static char ch[];
    static double alphabet[] = new double[26];
    static int N;
 
    static void func() {
        for (char x : ch) {
            if ('A' <= x && x <= 'Z')
                s.push(alphabet[x - 'A']);
            else if (x == '+') {
                double a = s.pop();
                double b = s.pop();
                s.push(b + a);
            } else if (x == '-') {
                double a = s.pop();
                double b = s.pop();
                s.push(b - a);
            } else if (x == '*') {
                double a = s.pop();
                double b = s.pop();
                s.push(b * a);
            } else {
                double a = s.pop();
                double b = s.pop();
                s.push(b / a);
            }
        }
 
        System.out.printf("%.2f\n", s.pop());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
 
        st = new StringTokenizer(br.readLine());
        ch = st.nextToken().toCharArray();
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            alphabet[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 1158 요세푸스 문제  (0) 2021.02.09
boj 1918 후위 표기식  (0) 2021.02.05
boj 2493 탑  (0) 2021.02.04
boj 6416 트리인가?  (0) 2021.02.04
boj 3190 뱀  (0) 2021.02.02

+ Recent posts