9012번: 괄호

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고

www.acmicpc.net

 

Language: Java

 

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
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Stack;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
        int T = Integer.parseInt(br.readLine());
 
        while (T-- > 0) {
            String s = br.readLine();
 
            Stack<Character> stack = new Stack<>();
            int i = 0;
            for (i = 0; i < s.length(); i++) {
                if (s.charAt(i) == '(') {
                    stack.push(s.charAt(i));
                } else {
                    if (stack.size() != 0) {
                        stack.pop();
                    } else {
                        break;
                    }
                }
            }
            if (i == s.length() && stack.size() == 0) {
                bw.write("YES\n");
            } else {
                bw.write("NO\n");
            }
        }
 
        bw.flush();
        bw.close();
 
    }
 
}
 
 
 

🤔 해설

1. 내부 if 조건문

    - 괄호의 시작이 '('여야 하므로, '(' 기준으로 push

2. 외부 if 조건문

    - stack이 완전히 비었을 때 뿐만 아니라, 전체 for을 순회해서 break가 있었는지도 함께 검사

 

⭐ push와 pop 순서가 중요해서 단순히 괄호의 개수를 구해서 여는 괄호==닫는 괄호로 계산하면 안됨

 

😮 이 외의 풀이

1. size() 대신 empty() 사용 가능

1
2
3
4
5
6
            if (i == s.length() && stack.empty()) {
                bw.write("YES\n");
            } else {
                bw.write("NO\n");
            }
 
 
 

 

2. 괄호의 개수를 counting

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
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
        int T = Integer.parseInt(br.readLine());
 
        while (T-- > 0) {
            String s = br.readLine();
 
            int num = 0;
            for (int i = 0; i < s.length(); i++) {
                if (s.charAt(i) == '(') {
                    num++;
                } else {
                    num--;
                if(num<0break;
                }
                
           }
 
            if (num == 0) {
                bw.write("YES\n");
            } else {
                bw.write("NO\n");
            }
        }
 
        bw.flush();
        bw.close();
 
    }
 
}
 
 
 

1. 내부 if 조건문

    - 닫는 괄호가 먼저 입력되어 -가 될 경우(=stack에서 더이상 pop 할 요소가 없는 경우) break를 통해서 NO 출력

    - num이 감소할 때만, -가 나타날 수 있으므로 break문도 else안에 입력

 

 

🔗 소스 코드
HJ0216/TIL/BOJ

 

 

10773번: 제로

첫 번째 줄에 정수 K가 주어진다. (1 ≤ K ≤ 100,000) 이후 K개의 줄에 정수가 1개씩 주어진다. 정수는 0에서 1,000,000 사이의 값을 가지며, 정수가 "0" 일 경우에는 가장 최근에 쓴 수를 지우고, 아닐 경

www.acmicpc.net

 

Language: Java

 

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.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Stack;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
        int num = Integer.parseInt(br.readLine());
 
        Stack<Integer> stack = new Stack<>();
        while(num-->0) {
            int i = Integer.parseInt(br.readLine());
            if(i!=0) {
                stack.add(i);
            } else {
                stack.remove(stack.size()-1);
            }
        }
        
        br.close();
        
        int sum = 0;
        
        for(int i=0; i<stack.size(); i++) {
            sum += stack.get(i);
        }
        
        bw.write(sum+"");
        bw.flush();
        bw.close();
    }
 
}
 
 
 

🤔 해설

1. if 조건문

    - 0이 아닌 값이 입력될 때, stack remove 시, stack.size를 활용하여 가장 최근에 입력된 수부터 제거

    (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
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Stack;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
        int num = Integer.parseInt(br.readLine());
 
        Stack<Integer> stack = new Stack<>();
        while (num-- > 0) {
            int i = Integer.parseInt(br.readLine());
            if (i != 0) {
                stack.push(i);
            } else {
                stack.pop();
            }
        }
 
        br.close();
 
        int sum = 0;
 
        for (int i : stack) {
            sum += i;
        }
 
        bw.write(sum + "");
        bw.flush();
        bw.close();
    }
 
}
 
 
 

1. Stack 내장 메서드 활용: push(), pop()

2. 향상된 for 반복문

 

 

 

🔗 소스 코드
HJ0216/TIL/BOJ

 

📚 참고 자료

 

[백준] 10773번 : 제로 - JAVA [자바]

www.acmicpc.net/problem/10773 10773번: 제로 첫 번째 줄에 정수 K가 주어진다. (1 ≤ K ≤ 100,000) 이후 K개의 줄에 정수가 1개씩 주어진다. 정수는 0에서 1,000,000 사이의 값을 가지며, 정수가 "0" 일 경우에는

st-lab.tistory.com

 

 

11650번: 좌표 정렬하기

첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.

www.acmicpc.net

 

Language: Java

 

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.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
        int num = Integer.parseInt(br.readLine());
 
        int[][] intArrXY = new int[num][2];
 
        for (int i = 0; i < num; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");
 
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
 
            intArrXY[i][0= a;
            intArrXY[i][1= b;
 
        }
 
        Arrays.sort(intArrXY, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[0!= o2[0] ? o1[0- o2[0] : o1[1- o2[1];
            }
        });
 
        for (int i = 0; i < num; i++) {
            bw.write(intArrXY[i][0+ " " + intArrXY[i][1+ "\n");
        }
 
        bw.flush();
        bw.close();
    }
 
}
 
 
 

🤔 해설

1. sort()

    - 이중 배열의 경우, 기존 sort 메서드를 통해 정렬할 수 없으므로 정렬기준을 오버라이딩하여 이차원 배열 정렬

2. @Override

    - Comparator 클래스에서 compare 메서드 Override

    - 배열의 첫번째 요소가 다르면 첫번째 요소로 정렬, 같으면 두 번째 요소로 정렬

    - 예시

        - 입력값: (3, 4), (1, 1), (1, -1)

        - intArr[0][0] = 3, intArr[0][1] = 4

        - intArr[1][0] = 1, intArr[1][1] = 1

        - intArr[2][0] = 1, intArr[2][1] = -1

        - intArr = {{3, 4}, {1, 1}, {1, -1}}

        - int[] o1 = {3, 4}, int[] o2 = {1, 1}

        - int[0] o1 = 3, int[0] o2 = 1

        - int[0] o1 - int[0] o2 : 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
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
        int num = Integer.parseInt(br.readLine());
 
        int[][] intArrXY = new int[num][2];
 
        for (int i = 0; i < num; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");
 
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
 
            intArrXY[i][0= a;
            intArrXY[i][1= b;
 
        }
 
        Arrays.sort(intArrXY, (arr1, arr2) -> {
            if (arr1[0== arr2[0]) {
                return arr1[1- arr2[1];
            } else {
                return arr1[0- arr2[0];
            }
        });
 
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < num; i++) {
            sb.append(intArrXY[i][0+ " " + intArrXY[i][1+ "\n");
        }
 
        bw.write(sb + "");
        bw.flush();
        bw.close();
    }
 
}
 
 
 

1. 람다식(익명 클래스)를 Comparator 클래스 대신 사용

2. StringBuffer 사용

 

⭐ 메서드 사용 방법을 자세히 알고 싶으면, Eclipse 기준 ctrl + method 클릭

1
2
3
4
5
6
7
8
9
10
11
    public static <T> void sort(T[] a, Comparator<super T> c) {
        if (c == null) {
            sort(a);
        } else {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a, c);
            else
                TimSort.sort(a, 0, a.length, c, null00);
        }
    }
 
 
 

- sort 사용 시, 첫 번째 인자가 T[]이므로 T는 int[]

 

 

🔗 소스 코드
HJ0216/TIL/BOJ

 

📚 참고 자료

 

[Java] 2차원 배열 정렬 (오름차순, 내림차순, 다중 조건)

> 2차원 배열을 오름차순, 내림차순, 이외에 원하는 조건 등 여러가지 방법으로 정렬 하는 방법을 포스팅 합니다. 2차원 배열을 바로 Arrray.sort()를 통해 정렬하려고 하면 java.lang.ClassCastException: I ca

ifuwanna.tistory.com

 

[백준] 11650번 : 좌표 정렬하기 - JAVA [자바]

www.acmicpc.net/problem/11650 11650번: 좌표 정렬하기 첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항

st-lab.tistory.com

 

 

24313번: 알고리즘 수업 - 점근적 표기 1

f(n) = 7n + 7, g(n) = n, c = 8, n0 = 1이다. f(1) = 14, c × g(1) = 8이므로 O(n) 정의를 만족하지 못한다.

www.acmicpc.net

 

Language: Java

 

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.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
 
        int A = Integer.parseInt(st.nextToken());
        int B = Integer.parseInt(st.nextToken());
 
        int C = Integer.parseInt(br.readLine());
        int N = Integer.parseInt(br.readLine());
        
        int x = 1;
        for (x = 1; x <= N; x++) {
            if ((C - A) * x >= B) {
                break;
            }
        }
 
        if (x <= N && A<=C) {
            bw.write("1");
        } else {
            bw.write("0");
        }
 
        bw.flush();
        bw.close();
    }
 
}
 
 
 

🤔 해설

1. for 반복문

    - 수식을 만족하는 x가 있을 경우, N과 비교하여 O(n)을 만족하는지 판단

🚨 A<=C 조건식 추가

 ax + b <= cx

b<=(c-a)x

에서 x의 범위를 살펴보기 위해서 총 3가지 가능성 고려

    - c=a

        - 특정값 이상의 모든 x에 대해서 부등식을 만족할 수 있음

        - 예: b=0일 경우, N과 무관하여 N보다 크거나 같은 모든 x에 대해서 부등식 만족

    - c>a

        - b/(c-a)<=x에서 b/(c-a)보다 크거나 같고 x보다 작거나 같은 N을 찾을 수 있음

        - 예: b=10, c=2, a=1일 경우, N>=10까지 O(n)을 만족

            - N=9일 경우, x가 9인 경우부터 판단할 수 있는데 부등식을 만족하지 않으므로 O(n) 불만족

    - c<a

        - b/(c-a)>=x에서 x는 N보다 크거나 같은 수로 값의 범위가 없으므로 양의 무한대까지 커질 수 있음

        - c<a를 만족하는 x가 있을 수 없음

        - O(n)을 판별하는 조건식에서 c<a일 경우는 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
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
 
        int A = Integer.parseInt(st.nextToken());
        int B = Integer.parseInt(st.nextToken());
 
        int C = Integer.parseInt(br.readLine());
        int N = Integer.parseInt(br.readLine());
 
        int fn = A * N + B;
        int gn = C * N;
 
        if (C >= A && fn <= gn) {
            bw.write("1");
        } else {
            bw.write("0");
        }
 
        bw.flush();
        bw.close();
    }
 
}
 
 
 

- for 반복문 사용하지 않고, 조건식으로 판별

 

 

 

 

2581번: 소수

M이상 N이하의 자연수 중 소수인 것을 모두 찾아 첫째 줄에 그 합을, 둘째 줄에 그 중 최솟값을 출력한다.  단, M이상 N이하의 자연수 중 소수가 없을 경우는 첫째 줄에 -1을 출력한다.

www.acmicpc.net

 

Language: Java

 

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
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 
        int min = Integer.parseInt(br.readLine());
        int max = Integer.parseInt(br.readLine());
 
        if(min==1) {
            calPrimeNum(min+1, max);
        } else {
            calPrimeNum(min, max);    
        }
        
    }
 
    public static void calPrimeNum(int min, int max) throws IOException {
 
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
        boolean[] bArr = new boolean[10001];
 
        for (int i = min; i <= max; i++) {
            for (int j = 2; j < i; j++) {
                if (i % j == 0) {
                    bArr[i] = true;
                    break;
                }
            }
        }
 
        int last = 0;
        int sum = 0;
 
        while (max >= min) {
            if (!bArr[max]) {
                sum += max;
                last = max;
            }
 
            max--;
        }
 
        if (last == 0) {
            bw.write(-1 + "");
        } else {
            bw.write(sum + "\n" + last);
        }
 
        bw.flush();
        bw.close();
    }
 
}
 
 
 

🤔 해설

1. main() - if 조건문

    - 1인 소수가 아니므로 min==1인 경우에는 calPrimeNum()에서 따로 조건문 처리를 해야하지만, 복잡해지는 걸 방지하기 위해 main()에서 먼저 처리

2. calPrimeNum()

    - for 반복문

        - min ~ max 까지 2이상의 수로 나누어 떨어질 경우, boolean 값 false(Default) → true로 변환

        - 소수가 아닐 경우, break를 활용하여 시간 단축

    - while 반복문

        - 최소값을 구하기 위해 max부터 last 변수에 대입

    - if 조건문

        - last == 0 일 경우, 소수가 없는 것이므로 -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
57
58
59
60
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 
        int min = Integer.parseInt(br.readLine());
        int max = Integer.parseInt(br.readLine());
 
        if(min==1) {
            calPrimeNum(min+1, max);
        } else {
            calPrimeNum(min, max);    
        }
        
    }
 
    public static void calPrimeNum(int min, int max) throws IOException {
 
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
        boolean[] bArr = new boolean[10001];
 
        for (int i = min; i <= max; i++) {
            for (int j = 2; j <= Math.sqrt(i); j++) {
                if (i % j == 0) {
                    bArr[i] = true;
                    break;
                }
            }
        }
 
        int last = 0;
        int sum = 0;
 
        while (max >= min) {
            if (!bArr[max]) {
                sum += max;
                last = max;
            }
 
            max--;
        }
 
        if (last == 0) {
            bw.write(-1 + "");
        } else {
            bw.write(sum + "\n" + last);
        }
 
        bw.flush();
        bw.close();
    }
 
}

 
 

- 로직은 그대로지만, 소수 판별 범위를 제곱근까지로 축소

 

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.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
 
public class Main {
 
    public static boolean[] bArr;
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
 
        int min = Integer.parseInt(br.readLine());
        int max = Integer.parseInt(br.readLine());
 
        calPrimeNum(min, max);
 
        int sum = 0;
        int first = 0;
        for (int i = max; i >= min; i--) {
            if (!bArr[i]) {
                sum += i;
                first = i;
            }
        }
 
        if (first != 0) {
            bw.write(sum + "\n" + first);
        } else {
            bw.write("-1");
        }
 
        bw.flush();
        bw.close();
 
    }
 
    public static void calPrimeNum(int min, int max) throws IOException {
        bArr = new boolean[max + 1];
 
        bArr[0= true;
        bArr[1= true;
 
        for (int i = 2; i < Math.sqrt(max); i++) {
            if (bArr[i]) {
                continue;
            }
 
            for (int j = i * i; j < bArr.length; j += i) {
                bArr[j] = true;
            }
        }
 
    }
 
}
 
 

- calPrimeNum()

1. bArr

    - 소수 판별 배열을 전역으로 설정하여, 2개의 메서드에서 공유

    - 0, 1을 true로 변경하여 소수로 처리되지 않도록 함

2. for 반복문

    - j를 i * i부터 시작하는 이유

        - i가 소수가 아닐 경우, 이전 for문에서 이미 처리 처리되어 if 조건문에 의해 다음 숫자로 넘어감

        - i가 소수일 경우, bArr값이 false로 유지

        - i * 2 = 2의 배수, i * 3 = 3의 배수, ... , i * (i-1) = (i-1)의 배수

    - j에 i를 더해서 배수를 계산

 

 

 

🔗 소스 코드
HJ0216/TIL/BOJ

 

📚 참고 자료

 

[백준] 2581번 : 소수 - JAVA [자바]

https://www.acmicpc.net/problem/2581 2581번: 소수 M이상 N이하의 자연수 중 소수인 것을 모두 찾아 첫째 줄에 그 합을, 둘째 줄에 그 중 최솟값을 출력한다. 단, M이상 N이하의 자연수 중 소수가 없을 경우는

st-lab.tistory.com