www.acmicpc.net/problem/1002

 

1002번: 터렛

각 테스트 케이스마다 류재명이 있을 수 있는 위치의 수를 출력한다. 만약 류재명이 있을 수 있는 위치의 개수가 무한대일 경우에는 -1을 출력한다.

www.acmicpc.net

이 문제는 두 사람의 위치와 그 위치에서 각각 보이는 적까지의 거리가 주어지며 수학적 지식이 필요한 문제입니다.

저는 원의 반지름과 두 점 사이의 거리를 이용하여 해결하였습니다.

 

A의 좌표가 주어지고, A가 계산한 적까지의 거리를 반지름이라고 생각하시면 됩니다.

B도 같은 방법으로 하면 두개의 원이 그려집니다.

그러면 이 문제는 두 원의 접점의 갯수를 구하는 문제가 됩니다.

두 원이 접하는 경우는 두가지인데 외접과 내접 모두 생각을 해야합니다.

 

두 점 사이의 거리 = d

A의 반지름 = r1 (더 짧은 반지름)

B의 반지름 = r2 (더 긴 반지름)

라고 하였을 때

 

d > r1 + r2    ->    접하지 않으므로 0개

d == r1 + r2  ->    접점이 1개(외접)

d < r1 + r2    ->    접점이 2개이거나 내접여부 확인

 

d + r1 == r2  ->    접점이 1개(내접)

d + r1 > r2    ->    접점이 2개

나머지 -> 0

 

으로 계산하였습니다.

 

 

 
 
 
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
70
71
72
73
74
75
76
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 class Circle {
        double x;
        double y;
        double r;
    }
 
    static Circle A, B;
    static double d;
    static int ans;
 
    static void swap() {
        Circle tmp = A;
        A = B;
        B = tmp;
    }
 
    static void func() {
        if (A.r > B.r) {
            swap();
        }
 
        if (A.x == B.x && A.y == B.y && A.r == B.r)
            ans = -1;
        else if (d == A.r + B.r)
            ans = 1;
        else if (d > A.r + B.r)
            ans = 0;
        else {
            if (d + A.r == B.r)
                ans = 1;
            else if (d + A.r > B.r)
                ans = 2;
            else
                ans = 0;
        }
    }
 
    static void print() {
        sb.append(ans + "\n");
        ans = 0;
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        A.x = Double.parseDouble(st.nextToken());
        A.y = Double.parseDouble(st.nextToken());
        A.r = Double.parseDouble(st.nextToken());
        
        B.x = Double.parseDouble(st.nextToken());
        B.y = Double.parseDouble(st.nextToken());
        B.r = Double.parseDouble(st.nextToken());
        d = Math.sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
    }
 
    public static void main(String[] args) throws Exception {
        st = new StringTokenizer(br.readLine());
        int tc = Integer.parseInt(st.nextToken());
        while (tc-- > 0) {
            A = new Circle();
            B = new Circle();
            input();
            func();
            print();
        }
        System.out.println(sb.toString());
    }
}
cs

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

boj 13136 Do Not Touch Anything  (0) 2022.10.25
boj 1837 암호제작  (0) 2021.02.04
boj 15740 A+B - 9  (0) 2021.01.31

www.acmicpc.net/problem/9657

 

9657번: 돌 게임 3

상근이가 게임을 이기면 SK를, 창영이가 게임을 이기면 CY을 출력한다.

www.acmicpc.net

dp로 해결할 수 있는 문제입니다.

 

상근이가 게임을 먼저 시작하고, 한 번에 가져갈 수 있는 돌의 갯수는 1개, 3개, 4개 입니다.

 

마지막에 돌은 가져간 사람은 승리하므로 dp[1] = true, dp[3] = true, dp[4] = true를 초기값으로 잡습니다.

그리고 dp[5]부터 dp[N]까지 반복문을 돌립니다.

 

여기서 i번째에서 돌을 가져갔을 때 남아있는 돌의 갯수에 따른 승패여부를 확인해야합니다.

돌을 1개 가져갔을 때 i - 1,

돌을 3개 가져갔을 때 i - 3,

돌을 4개 가져갔을 때 i - 4이므로

dp[i - 1], dp[i - 3], dp[i - 4]의 상황을 모두 체크해야합니다.

 

두 플레이어는 이기기 위해 최선을 다한다고 생각하고,

돌을 가져갔을 때 dp[i - 1], dp[i - 3], dp[i - 4] 모두가 true면 상대방이 무조건 이기는 경우이므로 false입니다.

반대로 dp[i - 1], dp[i - 3], dp[i - 4] 중 하나라도 false인 경우가 있으면 그 경우를 선택하면 무조건 이기므로 true입니다.

 

 

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
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 boolean dp[] = new boolean[1001];
    static int N;
 
    static void func() {
        dp[1= true;
        dp[3= true;
        dp[4= true;
        for (int i = 5; i <= N; i++) {
            if (dp[i - 1&& dp[i - 3&& dp[i - 4])
                dp[i] = false;
            else
                dp[i] = true;
        }
    }
    
    static void print() {
        if(dp[N])
            System.out.println("SK");
        else
            System.out.println("CY");
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

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

boj 5573 산책  (0) 2021.02.04
boj 17528 Two Machines  (0) 2021.01.28
boj 2096 내려가기  (0) 2021.01.22
boj 1103 게임  (0) 2021.01.22
boj 12852 1로 만들기 2  (0) 2021.01.22

www.acmicpc.net/problem/4889

 

4889번: 안정적인 문자열

입력은 여러 개의 데이터 세트로 이루어져 있다. 각 데이터 세트는 한 줄로 이루어져 있다. 줄에는 여는 괄호와 닫는 괄호만으로 이루어진 문자열이 주어진다. 문자열의 길이가 2000을 넘는 경우

www.acmicpc.net

괄호가 주어지는대로 그리디하게 해결할 수 있는 문제입니다.

 

'{'가 주어지면 스택에 바로 push합니다.

'}'일때 스택이 비어있으면 ans에 1을 더하고 방향을 바꿔 '{'로 스택에 push합니다.

스택이 비어있지 않으면 pop을 해주면 됩니다.

 

이 과정을 반복한 후에 스택이 비어있지 않으면 '{'이 짝수개 남아있다는 말이 됩니다.

그래서 마지막에 s.size()/2를 더해주고 출력합니다.

 

 

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
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 int ans = 0;
 
    static void func() {
        for (char x : ch) {
            if (x == '{') {
                s.push(x);
            } else {
                if (s.isEmpty()) {
                    ans++;
                    s.push('{');
                } else
                    s.pop();
            }
        }
 
        ans += (s.size() / 2);
        sb.append(ans + "\n");
        ans = 0;
        while (!s.isEmpty())
            s.pop();
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        ch = st.nextToken().toCharArray();
    }
 
    public static void main(String[] args) throws Exception {
        for (int T = 1;; T++) {
            input();
            if (ch[0== '-')
                break;
 
            sb.append(T + ". ");
            func();
        }
        
        System.out.println(sb.toString());
    }
}
cs

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

boj 11279 최대 힙  (0) 2021.01.31
boj 1927 최소 힙  (0) 2021.01.31
boj 2504 괄호의 값  (0) 2021.01.26
boj 6198 옥상 정원 꾸미기  (0) 2021.01.26
boj 1874 수택 수열  (0) 2021.01.25

www.acmicpc.net/problem/2504

 

2504번: 괄호의 값

4개의 기호 ‘(’, ‘)’, ‘[’, ‘]’를 이용해서 만들어지는 괄호열 중에서 올바른 괄호열이란 다음과 같이 정의된다. 한 쌍의 괄호로만 이루어진 ‘()’와 ‘[]’는 올바른 괄호열이다.  만일

www.acmicpc.net

작년에 특강들을때 풀었던 문제지만 기억이 가물가물했습니다..

 

먼저 괄호의 값이 결정되는 기준입니다.

1. () 의 값은 2이다.

2. [] 의 값은 3이다.

3. (X) 의 값은 2 * X이다.

4. [X] 의 값은 3 * X이다.

5. 괄호열 X와 괄호열 Y가 결합된 XY의 값은 X+Y이다.

 

입력이 ( ( ) ( ) ) 이런식으로 주어지면 2 * (2 + 2) = 8이라고 할 수 있는데

저는 2 * 2 + 2 * 2 = 8 의 방식으로 해결하였습니다.

 

변수는 답을 출력하는 ans와 중간 값을 나타내는 sum으로 2개를 사용하였습니다.

 

'(' / '['일 때 sum * 2 or sum * 3을 하고 push합니다.

')' / ']'일 때 연산을 수행하기 전에 먼저 괄호가 올바른 괄호열인지 확인해야합니다.

올바른 괄호열이 맞으면 바로 이전값이 여는 괄호일 경우에만 ans에 더해주고,

그 후에 sum / 2 or sum / 3을 하고 pop합니다.

올바른 괄호열이 아니면 0을 출력하고 return합니다.

 

모든 연산이 끝나고 스택이 괄호가 들어있으면 올바른 괄호열이 아니므로 0을 출력하고,

스택이 비어있으면 올바른 괄호열이므로 답을 출력합니다.

 

 

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.Stack;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static Stack<Character> s = new Stack<>();
    static char ch[];
    static int ans, sum = 1;
 
    static void func() {
        for (int i = 0; i < ch.length; i++) {
            if (ch[i] == '(') {
                sum *= 2;
                s.push(ch[i]);
            } else if (ch[i] == '[') {
                sum *= 3;
                s.push(ch[i]);
            } else if (ch[i] == ')') {
                if (s.isEmpty() || s.peek() != '(') {
                    System.out.println(0);
                    return;
                }
 
                if (s.peek() == '(') {
                    if (ch[i - 1== '(')
                        ans += sum;
                    sum /= 2;
                    s.pop();
                }
            } else {
                if (s.isEmpty() || s.peek() != '[') {
                    System.out.println(0);
                    return;
                }
 
                if (s.peek() == '[') {
                    if (ch[i - 1== '[')
                        ans += sum;
                    sum /= 3;
                    s.pop();
                }
            }
        }
 
        if (!s.isEmpty())
            System.out.println(0);
        else
            System.out.println(ans);
    }
 
    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 1927 최소 힙  (0) 2021.01.31
boj 4889 안정적인 문자열  (0) 2021.01.26
boj 6198 옥상 정원 꾸미기  (0) 2021.01.26
boj 1874 수택 수열  (0) 2021.01.25
boj 17298 오큰수  (0) 2021.01.25

www.acmicpc.net/problem/6198

 

6198번: 옥상 정원 꾸미기

문제 도시에는 N개의 빌딩이 있다. 빌딩 관리인들은 매우 성실 하기 때문에, 다른 빌딩의 옥상 정원을 벤치마킹 하고 싶어한다. i번째 빌딩의 키가 hi이고, 모든 빌딩은 일렬로 서 있고 오른쪽으

www.acmicpc.net

바라보는 방향이 오른쪽이고, 그 방향에 자신보다 크거나 같은 높이의 건물과 그 이후의 건물의 옥상은 볼 수 없습니다.

 

저는 순차탐색으로 스택에 높이와 인덱스를 넣어가며 비교하였습니다.

 

먼저 s.peek의 높이가 현재 높이보다 작거나 같으면 자신 이후의 건물을 볼 수 없으므로 pop을 해줍니다.

이때 pop을 해주면서 현재의 인덱스와 삭제할 건물의 인덱스 사이에 존재하는 번호의 갯수를 ans에 더해줍니다.

 

이 작업이 끝나고 스택에 값이 남아있으면 s.peek()부터 작은 순서대로 pop이 될 것입니다.

s.peek()이 가장 마지막에 있는 건물이기 때문에 고정값(pre)으로 하고 pop하는 건물의 인덱스와 pre의 차이만큼 더해줍니다.

 

 

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
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<int[]> s = new Stack<>();
    static int list[];
    static int N;
    static long ans;
 
    static void func() {
        for (int i = 0; i < N; i++) {
            while (!s.isEmpty() && s.peek()[0<= list[i]) {
                ans += (i - (s.peek()[1+ 1));
                s.pop();
            }
 
            s.push(new int[] { list[i], i });
        }
 
        int pre = N - 1;
        while (!s.isEmpty()) {
            ans += (pre - s.peek()[1]);
            s.pop();
        }
        
        System.out.println(ans);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 4889 안정적인 문자열  (0) 2021.01.26
boj 2504 괄호의 값  (0) 2021.01.26
boj 1874 수택 수열  (0) 2021.01.25
boj 17298 오큰수  (0) 2021.01.25
boj 4358 생태학  (0) 2021.01.25

www.acmicpc.net/problem/15652

 

15652번: N과 M (4)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

N과M 4번째 문제입니다.

같은 수를 여러번 골라도 되고, 수열은 비내림차순이어야 합니다.

비내림차순 이라는 말은 같거나 큰 숫자를 골라야합니다.

즉, 중복이 가능하다는 것입니다.

 

작은수를 고르면 안되기때문에 다음 수로 넘어갈 때는 현재 수인 i를 그대로 넘겨주면 됩니다.

 

 

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
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 list[];
    static int N, M;
 
    static void dfs(int num, int cnt) {
        if (cnt == M) {
            for (int i = 0; i < M; i++) {
                sb.append(list[i] + " ");
            }
            sb.append("\n");
            return;
        }
 
        for (int i = num; i <= N; i++) {
            list[cnt] = i;
            dfs(i, cnt + 1);
            list[cnt] = 0;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        list = new int[M];
    }
 
    public static void main(String[] args) throws Exception {
        input();
        dfs(10);
        System.out.println(sb.toString());
    }
}
cs

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

boj 15655 N과 M (6)  (0) 2021.01.27
boj 15654 N과 M (5)  (0) 2021.01.27
boj 15651 N과 M (3)  (0) 2021.01.26
boj 15650 N 과 M (2)  (0) 2021.01.26
boj 15649 N 과 M (1)  (0) 2021.01.26

www.acmicpc.net/problem/15651

 

15651번: N과 M (3)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

N과M 3번째 문제입니다.

 

이 문제는 같은 수를 중복해서 선택할 수 있기때문에 중복체크를 안하는 것이 맞습니다.

나머지는 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
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 list[];
    static int N, M;
 
    static void dfs(int cnt) {
        if (cnt == M) {
            for (int x : list) {
                sb.append(x + " ");
            }
            sb.append("\n");
            return;
        }
 
        for (int i = 1; i <= N; i++) {
            list[cnt] = i;
            dfs(cnt + 1);
            list[cnt] = 0;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        list = new int[M];
    }
 
    public static void main(String[] args) throws Exception {
        input();
        dfs(0);
        System.out.println(sb.toString());
    }
}
cs

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

boj 15654 N과 M (5)  (0) 2021.01.27
boj 15652 N 과 M (4)  (0) 2021.01.26
boj 15650 N 과 M (2)  (0) 2021.01.26
boj 15649 N 과 M (1)  (0) 2021.01.26
boj 2580 스도쿠  (0) 2021.01.22

www.acmicpc.net/problem/15650

 

15650번: N과 M (2)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

N과 M 두번째 문제입니다.

 

첫번째 문제와 다른 점은 고른 수열이 오름차순이라는 점입니다.

순서를 보는 문제라고 생각하시면 됩니다.

 

 

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
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 boolean visit[];
    static int list[];
    static int N, M;
 
    static void dfs(int num, int cnt) {
        if (cnt == M) {
            for (int x : list) {
                sb.append(x + " ");
            }
            sb.append("\n");
            return;
        }
 
        for (int i = num; i <= N; i++) {
            if (visit[i])
                continue;
 
            visit[i] = true;
            list[cnt] = i;
            dfs(i + 1, cnt + 1);
            list[cnt] = 0;
            visit[i] = false;
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        list = new int[M];
        visit = new boolean[N + 1];
    }
 
    public static void main(String[] args) throws Exception {
        input();
        dfs(10);
        System.out.println(sb.toString());
    }
}
cs

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

boj 15652 N 과 M (4)  (0) 2021.01.26
boj 15651 N과 M (3)  (0) 2021.01.26
boj 15649 N 과 M (1)  (0) 2021.01.26
boj 2580 스도쿠  (0) 2021.01.22
boj 1759 암호 만들기  (0) 2021.01.22

www.acmicpc.net/problem/15649

 

15649번: N과 M (1)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

기본적인 백트래킹으로 해결할 수 있는 문제입니다.

 

이 문제에서는 수의 순서를 따지기때문에 1,2,3,4와 1,2,4,3을 다른 수열이라고 보시면 됩니다.

 

 

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
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<>();
    static boolean[] visit = new boolean[9];
    static int N, M;
 
    static void dfs(int cnt) {
        if (cnt == M) {
            for (Integer x : list) {
                sb.append(x + " ");
            }
            sb.append("\n");
            return;
        }
 
        for (int i = 1; i <= N; i++) {
            if (visit[i])
                continue;
 
            visit[i] = true;
            list.add(i);
            dfs(cnt + 1);
            list.remove(list.size() - 1);
            visit[i] = false;
        }
    }
 
    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();
        dfs(0);
        System.out.println(sb.toString());
    }
}
cs

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

boj 15651 N과 M (3)  (0) 2021.01.26
boj 15650 N 과 M (2)  (0) 2021.01.26
boj 2580 스도쿠  (0) 2021.01.22
boj 1759 암호 만들기  (0) 2021.01.22
boj 1062 가르침  (0) 2021.01.22

 

www.acmicpc.net/problem/1874

 

1874번: 스택 수열

1부터 n까지에 수에 대해 차례로 [push, push, push, push, pop, pop, push, push, pop, push, push, pop, pop, pop, pop, pop] 연산을 수행하면 수열 [4, 3, 6, 8, 7, 5, 2, 1]을 얻을 수 있다.

www.acmicpc.net

스택에 1~N을 순서대로 push, pop 과정을 반복하면서 입력에 주어진 순서대로 pop을 할 수 있는지 출력하는 문제입니다.

 

아래의 예시를 이용하여 리뷰하겠습니다.

8
4
3
6
8
7
5
2
1

N = 8, list[] = {4, 3, 6, 8, 7, 5, 2, 1} 입니다.

 

push 1 -> s.peek = 1, list[idx] = 4 (s.peek != list[idx] 이므로 (+))

push 2 -> s.peek = 2, list[idx] = 4 (s.peek != list[idx] 이므로 (+))

push 3 -> s.peek = 3, list[idx] = 4 (s.peek != list[idx] 이므로 (+))

push 4 -> s.peek = 4, list[idx] = 4 (s.peek == list[idx] 이므로 (-)후에 idx++)

              s.peek = 3, list[idx] = 3 (s.peek == list[idx] 이므로 (-)후에 idx++)

              s.peek = 2, list[idx] = 6 (s.peek != list[idx] 이므로 다음 진행)

push 5 -> s.peek = 5, list[idx] = 6 (s.peek != list[idx] 이므로 (+))

push 6 -> s.peek = 6, list[idx] = 6 (s.peek == list[idx] 이므로 (-)후에 idx++)

              s.peek = 5, list[idx] = 8 (s.peek != list[idx] 이므로 다음 진행)

push 7 -> s.peek = 7, list[idx] = 8 (s.peek != list[idx] 이므로 (+))

push 8 -> s.peek = 8, list[idx] = 8 (s.peek == list[idx] 이므로 (-)후에 idx++)

              s.peek = 7, list[idx] = 7 (s.peek == list[idx] 이므로 (-)후에 idx++)

              s.peek = 5, list[idx] = 5 (s.peek == list[idx] 이므로 (-)후에 idx++)

              s.peek = 2, list[idx] = 2 (s.peek == list[idx] 이므로 (-)후에 idx++)

              s.peek = 1, list[idx] = 1 (s.peek == list[idx] 이므로 (-)후에 idx++)

 

여기서 8까지 push 완료하였고, 스택 안의 모든 숫자가 pop되었으므로 순서대로 출력해주시면 됩니다.

만약에 모든 push가 이루어졌는데 pop이 더이상 진행되지 못할 경우에는 NO를 출력해주셔야합니다.

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
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<Integer> s = new Stack<>();
    static int list[];
    static int N;
 
    static void func() {
        int idx = 0;
        for (int i = 1; i <= N; i++) {
            s.add(i);
            sb.append("+\n");
            while (!s.isEmpty() && idx < N && s.peek() == list[idx]) {
                s.pop();
                sb.append("-\n");
                idx++;
            }
        }
        
        while(!s.isEmpty() && idx < N && s.peek() == list[idx]) {
            s.pop();
            sb.append("-\n");
            idx++;
        }
        if(!s.isEmpty()) {
            sb = new StringBuffer();
            sb.append("NO\n");
        }
        
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N];
 
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 2504 괄호의 값  (0) 2021.01.26
boj 6198 옥상 정원 꾸미기  (0) 2021.01.26
boj 17298 오큰수  (0) 2021.01.25
boj 4358 생태학  (0) 2021.01.25
boj 5639 이진 검색 트리  (0) 2021.01.24

www.acmicpc.net/problem/17298

 

17298번: 오큰수

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다.

www.acmicpc.net

스택으로 구현할 수 있고, 시간초과에 주위해야하는 문제입니다.

자바에서는 출력만으로도 시간초과가 나올 수 있기때문에 반복적인 System.out.println 보다는

StringBuffer, StringBuilder, BufferedWriter 중에서 사용해야합니다.

 

우선 오큰수는 자신의 오른쪽에 있는 숫자들 중에서 자신보다 큰 수 중에 가장 왼쪽에 있는 수를 말합니다.

 

저는 이 문제를 해결하기 위해 수열의 역순으로 탐색을 하였습니다.

list[i]를 스택에 넣기 전에 자신보다 작은 값들을 전부 pop해준 후에 남아있는 스택의 top에 있는 값이 오큰수 입니다.

 

먼저 스택이 비어있다면 자신이 가장 큰 수이므로 -1입니다.

비어있지 않다면 스택의 top이 오큰수입니다.

 

이 값들을 StringBuffer에 다 append를 해준 후에 마지막에 sb.toString()을 출력해주시면 되겠습니다.

 

 

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
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<Integer> s = new Stack<>();
    static int list[], ans[];
    static int N;
 
    static void print() {
        for (int i = 0; i < N; i++) {
            sb.append(ans[i] + " ");
        }
 
        System.out.println(sb.toString() + "\n");
    }
 
    static void func() {
        for (int i = N - 1; i >= 0; i--) {
            while (!s.isEmpty() && s.peek() <= list[i])
                s.pop();
 
            if (s.isEmpty())
                ans[i] = -1;
            else
                ans[i] = s.peek();
 
            s.add(list[i]);
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N];
        ans = new int[N];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

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

boj 6198 옥상 정원 꾸미기  (0) 2021.01.26
boj 1874 수택 수열  (0) 2021.01.25
boj 4358 생태학  (0) 2021.01.25
boj 5639 이진 검색 트리  (0) 2021.01.24
boj 1991 트리 순회  (0) 2021.01.22

www.acmicpc.net/problem/4358

 

4358번: 생태학

프로그램은 여러 줄로 이루어져 있으며, 한 줄에 하나의 나무 종 이름이 주어진다. 어떤 종 이름도 30글자를 넘지 않으며, 입력에는 최대 10,000개의 종이 주어지고 최대 1,000,000그루의 나무가 주어

www.acmicpc.net

나무의 각 종의 이름이 입력으로 들어오면 사전순으로 각 종의 비율을 출력하는 문제입니다.

사전순으로 출력하기 위해 Map 중에서 TreeMap을 사용하였습니다.

 

이름이 주어질 때마다 새로운 이름이면 생성하여 맵에넣고, 기존에 있던 이름이면 +1.0한 값을 맵에 넣어줍니다.

 

맵의 데이터들을 출력하기 위해 Entry를 사용하였고, e.getKey()(이름)과 e.getValue()/N *100 (비율)을 출력하였습니다.

 

 

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.Map.Entry;
import java.util.TreeMap;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static String st;
    static TreeMap<String, Double> m = new TreeMap<>();
    static double N;
 
    static void func() {
        StringBuffer sb = new StringBuffer();
        for (Entry<String, Double> e : m.entrySet()) {
            sb.append(e.getKey() + " " + String.format("%.4f", e.getValue() * 100.0 / N) + "\n");
        }
 
        System.out.println(sb.toString());
    }
 
    static void input() throws Exception {
        while (true) {
            st = br.readLine();
            if (st == null || st.length() == 0)
                break;
 
            if (m.containsKey(st)) {
                double a = m.get(st);
 
                m.put(st, a + 1.0);
            } else {
                m.put(st, 1.0);
            }
 
            N += 1.0;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 1874 수택 수열  (0) 2021.01.25
boj 17298 오큰수  (0) 2021.01.25
boj 5639 이진 검색 트리  (0) 2021.01.24
boj 1991 트리 순회  (0) 2021.01.22
boj 11003 최솟값 찾기  (0) 2021.01.22

+ Recent posts