#유형 : 문자열

#난이도 : LV2

# 자바의 StringBuilder 클래스나 StringBuffer를 사용하면 편하게 풀 수 있던 문제

이전 문자열을 체크하면서 스트링을 추가하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.*;
class Solution {
    public String solution(String s) {
        StringBuilder answer = new StringBuilder();
        answer.append(Character.toUpperCase(s.charAt(0)));
        for(int i=1; i<s.length(); i++){
            if(s.charAt(i) == ' '){
                answer.append(" ");
            }else if(s.charAt(i-1== ' '){
                answer.append(Character.toUpperCase(s.charAt(i)));
            }else{
                answer.append(Character.toLowerCase(s.charAt(i)));
            }
        }
        
        return answer.toString();
    }
}
cs

#유형 : 수학

#난이도 : LV2

# 최대공약수와 최소공배수의 원리를 이해하고 있으면 쉽게 접근할 수 있던 문제

# 너무 오랜만에 풀어서 최소공배수 원리를 까먹었다.. 

* 최소공배수 = 두 수의 곱 / 두수의 최대공약수

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
    public int solution(int[] arr) {
        int answer = arr[0];
        
        for(int i=0; i<arr.length; i++){
            answer = lcm(answer, arr[i]);
        }
        return answer;
    }
    
    static int gcd(int a, int b){
        if(a%b == 0){
            return b;
        }
        
        return gcd(b, a%b);
    }
    
    static int lcm(int a, int b){
        return a*/ gcd(a,b);
    }
}
cs

#유형 : BFS

#난이도 : LV2

# 오랜만에 풀었던 BFS 문제, 동서남북으로 이동하며 조건에 따라 처리하면 된다.

1. 맨해튼거리가 2이하 이면서 응시자가 있다면 false return

2. O(가림막)이면서 맨해튼거리가 2미만이면 큐에 넣어서 탐색을 이어간다.

 

if(places[nextRow].charAt(nextCol) == 'P' && dist <= 2)

     return false;

else if(places[nextRow].charAt(nextCol) == 'O' && dist < 2)

     queue.offer(new Point(nextRow, nextCol));

 

 

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.util.*;
import java.awt.Point;
 
class Solution {
    static int moveX[] = {-1,0,1,0};
    static int moveY[] = {0,1,0,-1};
    
    
    public static int[] solution(String[][] places) {
            int[] answer = new int[places.length];
            
            for(int i=0; i<places.length; i++) {
                    String tmp[] = places[i];
                    
                    boolean isCheck = true;
                    for(int r=0; r<5 && isCheck; r++) {
                        for(int c=0; c<5 && isCheck; c++) {
                            if(tmp[r].charAt(c) == 'P') {
                                if(!bfs(r,c,tmp))
                                    isCheck = false;
                            }
                        }
                    }
                    answer[i] = isCheck ? 1 : 0;
            }
            
            
            
            return answer;
     }
    
     public static boolean bfs(int r, int c, String []places) {
         Queue<Point> queue = new LinkedList<Point>();
         
         queue.add(new Point(r,c));
         
         while(!queue.isEmpty()) {
             Point p = queue.poll();
             
             for(int d=0; d<4; d++) {
                 int nextRow = p.x + moveY[d];
                 int nextCol = p.y + moveX[d];
                 
                 if(nextCol<0 || nextRow<0 || nextCol>=5 || nextRow>=5 || (nextCol == c && nextRow == r))
                         continue;
                 
                 int dist = Math.abs(nextCol - c) + Math.abs(nextRow - r);
                 
                 if(places[nextRow].charAt(nextCol) == 'P' && dist <= 2)
                     return false;
                 else if(places[nextRow].charAt(nextCol) == 'O' && dist < 2)
                     queue.offer(new Point(nextRow, nextCol));
             }
         }
         
         return true;
     }
     
     
}
cs

#유형 : DFS, 순열

#난이도 : LV2

# LV2 치고는 머리를 꽤나 싸매야 했던 문제. 오랜만에 알고리즘 하다보니 감각이 사라진거같다.

 

우선 숫자와 연산자를 분리하여 각각 배열리스트에 담고 연산자의 우선순위를 정하며 가장 큰 절대값을 탐색하였다.

 

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
import java.util.*;
class Solution {
    static char op[] = {'+','-','*'};
    static long answer = 0;
    static boolean visit[] = new boolean[3];
    static ArrayList<Long> arrList = new ArrayList<>();
    static ArrayList<Character> opList = new ArrayList<>();
    
    
    public static long solution(String expression) {
        answer = 0;
        
        String num ="";
        for(int i=0; i<expression.length(); i++) {
                if(expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
                    num += expression.charAt(i);
                }else {
                    arrList.add(Long.parseLong(num));
                    num = "";
                    opList.add(expression.charAt(i));
                }
        }
        arrList.add(Long.parseLong(num));
        
        dfs(0new char[3]);
        
        return answer;
    }
    public static void dfs(int count, char p[]) {
        
            if(count == 3) {
                ArrayList<Long> arrNum = new ArrayList<>(arrList);
                ArrayList<Character> arrOp = new ArrayList<>(opList);
                
                for(int i=0; i<p.length; i++) {
                    for(int j=0; j<arrOp.size(); j++) {
                        if(p[i] == arrOp.get(j)) {
                            Long result = calc(arrNum.remove(j), arrNum.remove(j), p[i]);
                            arrNum.add(j, result);
                            arrOp.remove(j);
                            j--;
                        }
                    }
                }
                
                answer = Math.max(answer, Math.abs(arrNum.get(0)));
                return;
            }
            
            
            for(int i=0; i<3; i++) {
                if(!check[i]) {
                    check[i] = true;
                    p[count] = op[i];
                    dfs(count+1, p);
                    check[i] = false;
                }
            }
    }
    public static long calc(long num1, long num2, char op){
        if(op == '+'){
            return num1 + num2;
        }
        else if(op == '-'){
            return num1 - num2;
        }
        else{
            return num1 * num2;
        }
        
    }
}
cs

#유형 : 문자열, HashMap

#난이도 : LV2

# 입력받은 문자열 처리 후, 해시맵의 빈도수로 풀면 된다. 문제를 이해하기가 어려웠는데, 빈도수를 기반으로 접근하면 된다.

 

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.util.*;
 
class Solution {
    public static int[] solution(String s) {
        
        int[] answer = {};
        s = s.replaceAll("\\{""");
        s = s.replaceAll("\\}","");
        //s = s.trim();
        
        HashMap<String, Integer>  hashMap = new HashMap<>();
        //System.out.println(s);
        for(int i=0; i<s.length(); i++){
            int startIdx = i;
            int endIdx = startIdx;
            
            //char ch = s.charAt(endIdx);
            while(endIdx < s.length() && s.charAt(endIdx) != ','){
                    endIdx++;
            }
            
            String num = s.substring(startIdx, endIdx);
            //System.out.println(startIdx + "//" + endIdx+"||"+num);
            if(hashMap.containsKey(num)){
                    hashMap.put(num, hashMap.get(num)+1);
                }else{
                    hashMap.put(num, 1);
                }
                i = endIdx;
        }
        List<Map.Entry<String, Integer>> list = new ArrayList<>(hashMap.entrySet());
        Collections.sort(list, (o1, o2) -> {
            return o2.getValue().compareTo(o1.getValue());
        });
        
        answer = new int[list.size()];
        for(int i=0; i<answer.length; i++){
            
            answer[i] = Integer.parseInt(list.get(i).getKey());
            
            //System.out.println(Integer.parseInt(list.get(i).getKey()));
        }
        
        return answer;
    }
}
cs

#유형 : 시뮬레이션, 문자열, HashMap

#난이도 : LV2

# 문자열 처리를 많이 해봤다면 쉽게 풀 수 있다고 생각한다. 

 

문제 그대로, 입력받는 명령어에 따라 String 문자열을 배열에 넣고 처리하면 된다.

변경되는 닉네임을 어떻게 처리할지 생각하던 중, userId를 기준으로 바뀌는 닉네임은 HashMap의 put 메소드를 사용하면 된다고 생각했다. 해당 메소드는 가장 늦게 들어온 키값을 기준으로 갱신하기 때문에 딱 알맞다고 생각한다. 더 좋은 방법도 물론 있을것이다.

 

문자열 처리를 많이 해봤다면 쉽게 풀 수 있다.

 

 

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.util.*;
 
class Solution {
    public static String[] solution(String[] record) {
        
        String[] answer;
        
        ArrayList<String> arrList = new ArrayList<>();
        HashMap<StringString> historyMap = new HashMap<>();
        
        for(int i=0; i<record.length; i++){
            StringTokenizer st = new StringTokenizer(record[i]);
            
            String cmd = st.nextToken();
            String userId = st.nextToken();
            String userNickName="";
            
            if(!cmd.equals("Leave")) {
                    userNickName = st.nextToken();
            }
            
            if(cmd.equals("Enter")) {
                    arrList.add(userId + "님이 들어왔습니다.");
                    historyMap.put(userId, userNickName);
                    
            }
            else if(cmd.equals("Leave")) {
                    arrList.add(userId + "님이 나갔습니다.");
            }
            else {
                    historyMap.put(userId, userNickName);
            }
        }
        answer = new String[arrList.size()];
        
        for(int i=0; i<arrList.size(); i++) {
                String str = arrList.get(i);
                int idx = str.indexOf("님");
                String keyId = str.substring(0, idx);
                
                answer[i] = str.replace(keyId, historyMap.get(keyId));
            
            
        }
        
        
        return answer;
    }
}
cs

#유형 : 수학

#난이도 : lv2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
    public long solution(long w, long h) {
        long answer = 1;
        
        long tmp = Math.max(w,h);
        long tmp2 = Math.min(w,h);
        
        w = tmp2;
        h = tmp;
        answer = w * h - (w+h-gcd(h,w));
        return answer;
    }
    
    public long gcd(long x, long y){
        
        if(x % y == 0)
            return y;
        
        return gcd(y, x%y);
    }
}
cs

이런 문제의 경우, 보통 여러 케이스를 그려가며 반복되는 공통점을 찾는다.

 

우선 짝수의 경우를 먼저 살펴보자

8 x 12의 경우 96 - 16개

6 x 9의 경우 54 - 12개

4 x 6 의 경우 24 - 8

 

이 때, 사용할 수 없는 직사각형의 공통점은 w+h-(w,h)의 최대공약수 라는 것을 확인할 수 있다. 

 

그렇다면 홀수의 경우에도 같은 방법이 적용되는지 확인해보자.

 

 

위 그림은 (3,3)도 지나게 될것

3 x 4 의 경우 12 - 6 

 

 

2 x 3 의 경우 6 - 4 

 

둘다 홀수인 경우에도 W + H - ((W,H)의 최대공약수 1) 이 적용되는 것을 확인할 수 있다.

 

마지막으로, 홀수와 짝수가 같이 있는 경우를 살펴보자

 

 

1 x 2 의 경우 2 - 2 

5 x 2 의 경우 10 - 6

 

아까와 동일하다.

 

결과로, 사용할 수 없는 직사각형의 공통점은 w+h-(w,h)의 최대공약수가 맞다는 것을 확인할 수 있다.

 

#유형 : 그리디, 규칙

#난이도 : 실버 1

# 입력받는 숫자 N이 2^n일 경우, 물병을 하나로 합칠수 있음(2, 4, 8, 16 .. )

# 물병을 하나로 합쳐가며 K개를 넘기지 않도록 반복문을 돌린다.

 

1. 입력받는 숫자 N을 물병 하나로 합쳐간다.(N/=2)

2. 1번의 과정에서 나머지가 발생하는 경우 COUNT += 1

3. 반복문을 돌리며, COUNT가 K보다 작은 경우 리턴

4. 아닌 경우, 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.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class p1052 {
    static int N,K;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        
        int pls = 0;
        while(true) {
            
            int tmp = N + pls;
            int count = 0;
            
            while(tmp > 0) {
                
                if(tmp % 2 != 0)
                    count++;
                //System.out.println(tmp + " // " + count);
                tmp /= 2;
                
            }
            
            if(count <= K)
                break;
            
            pls++;
        }
        
        System.out.println(pls);
    }
}
 
cs

'백준' 카테고리의 다른 글

#백준_1038 괄호 - Java 자바  (0) 2021.11.21
#백준_9012 괄호 - Java 자바  (0) 2020.07.06
#백준_10828 스택 - Java 자바  (0) 2020.07.06
#백준_1629 곱셈 - Java 자바  (0) 2020.07.01
#백준_2096 내려가기 - Java 자바  (0) 2020.06.27

+ Recent posts