ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 1940, 1253, 12891(JAVA)
    Java/코딩테스트 2022. 7. 31. 02:41

    - start, end 2개의 포인트로 범위 지정해서 범위대로 이동하는 해결법으로 푸는 문제들이다. 

    - 오름차 순으로 정렬해서 사용하자

     

    📌 백준 1940

     

    📌 투 포인터 이동 원칙

    - 찾고자 하는 합이 기준치보다 큰 경우에는 end쪽을 줄이고, 작은 경우에는 start쪽을 올린다(증가) : while문안에서 이 조건을 검사

    - 15000이 넘지 않는 재료의 개수, 시간 제한 2초이기에 정렬을 사용할 수 있음

     

    import java.util.*;
    import java.io.*;
    
    public class Main {
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            int n = Integer.parseInt(br.readLine());
            int m = Integer.parseInt(br.readLine()); // 엔터 기준으로 입력되기 때문에 바로 readLine후 parse
            int [] materials = new int[n];
            StringTokenizer stringTokenizer = new StringTokenizer(br.readLine());
    
            for (int i = 0; i < n; i++) {
                materials[i] = Integer.parseInt(stringTokenizer.nextToken());
            }
            Arrays.sort(materials); // 배열 정렬
            int start = 0;
            int end = n-1;
            int count = 0;
    
            while (start < end) {
                if (materials[start] + materials[end] > m) {
                    end--;
                } 
                else if (materials[start] + materials[end] < m) {
                    start++;
                } 
                else {
                    count++;
                    start++;
                    end--;
                }
            }
    
            System.out.println(count);
        }
    }

     


     

    📌 백준 1253

    📌 자기 자신이 좋은 수에 포함되면 안 된다. 그래서 start와 end가 각각 i와 같은지 다른지 여부를 판단해야 한다. 이 부분 빼먹어서 실수했다. 

    📌 start와 end가 만나면 더 이상 수를 찾을 수 없으므로 종료조건을 이걸로 줄 것. 

    import java.util.*;
    import java.io.*;
    
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int num = sc.nextInt();
            int count = 0;
            long numbers[] = new long[num];
    
            for (int k = 0; k < num; k++) {
                numbers[k] = sc.nextLong();
            }
            Arrays.sort(numbers);
            for (int i = 0; i < num; i++) {
                int start = 0;
                int end = num-1;
                while (start < end) {
                    if (numbers[start] + numbers[end] == numbers[i]) {
                        if (start != i && end != i) {
                            count++;
                            break;
                        } 
                        else if (start == i) {
                            start++;
                        } 
                        else if (end == i) {
                            end--;
                        }
                    } 
                    else if(numbers[start] + numbers[end] > numbers[i]) {
                        end--;
                    }
                    else {
                        start++;
                    }
                }
            }
    
            System.out.println(count);
    
        }
    }

     


     

    📌 백준 12891

    <tmi> 

    너무 복잡해서 (?) 코드 한줄한줄에 썼다. 실버2도 힘든 코딩 실력.................................

    풀다가 막혀서 책 해설을 좀 찾아봤는데, removeChar함수 부분에서 stateArray와 checkArray 같은지 판별 후 checkCondition을 먼저 감소시켰어야 했는데 순서를 뒤집어서 틀렸었다. 답이 어쩐지 계속 안 나왔었다...^_^

    import java.util.*;
    import java.io.*;
    
    public class Main {
        static int checkArray[];
        static int stateArray[]; // ACGT 순서
        static int checkCondition;
    
        public static void main(String[] args) throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            StringTokenizer stringTokenizer= new StringTokenizer(reader.readLine());
    
            int wholeLen = Integer.parseInt(stringTokenizer.nextToken()); // 전체 문자열 길이
            int partLen = Integer.parseInt(stringTokenizer.nextToken()); // 부분 문자열 길이
            
            int result = 0;
            checkCondition = 0;
    
            char charArray[] = new char[wholeLen]; // 전체 문자열 입력받을 배열
            charArray = reader.readLine().toCharArray();
    
            checkArray = new int[4]; // ACGT 각각 몇개 들어있어야 하는지 조건 저장 위한 배열
            stateArray = new int[4]; // 지금 읽은 부분 문자열에 ACGT 몇개씩 들어있는지 상태 저장하기 위한 배열
    
            stringTokenizer = new StringTokenizer(reader.readLine());
            for (int i = 0; i < 4; i++) {
                checkArray[i] = Integer.parseInt(stringTokenizer.nextToken());
                if (checkArray[i] == 0) {
                    checkCondition++; // 만약 한 글자 아예 없어도 된다! 이 경우라면 condition 증가
                }
            }
    
            for (int j = 0; j < partLen; j++) {
                readChar(charArray[j]); // 맨 처음 초기 partLen 만큼 먼저 읽어주고, 그 다음 한 칸씩 이동. 
            }
            if (checkCondition == 4) {
                result++; // 처음 partLen만큼 읽었는데 만족한다면 일단 result 증가.
            }
    
            for (int i = partLen; i < wholeLen; i++) { 
                int start = i - partLen; // 시작 부분, 이동하면서 맨 앞은 버리기 때문에 얘는 제거가 필요;
                readChar(charArray[i]); // partLen위치부터 한 칸씩 이동하면서 읽음, 이 반복문에서 i가 마지막 인덱스
                removeChar(charArray[start]);
                if (checkCondition == 4) {
                    result++; // 한 칸 이동할 때마다 checkCondition 만족하나 안하나 검사
                }
            }
    
            System.out.println(result);
            
            reader.close();
        }
    
        public static void readChar(char element) {
            switch(element) {
                case 'A' :
                    stateArray[0]++;
                    if (stateArray[0] == checkArray[0]) {
                        checkCondition++;
                    }
                    break;
    
                case 'C' :
                    stateArray[1]++;
                    if (stateArray[1] == checkArray[1]) {
                        checkCondition++;
                    }
                    break;
    
                case 'G' :
                    stateArray[2]++;
                    if (stateArray[2] == checkArray[2]) {
                        checkCondition++;
                    }
                    break;
    
                case 'T' :
                    stateArray[3]++;
                    if (stateArray[3] == checkArray[3]) {
                        checkCondition++;
                    }
                    break;
            }
    
        }
    
        public static void removeChar(char element) {
            switch(element) {
                case 'A' :
                    if (stateArray[0] == checkArray[0]) {
                        checkCondition--; // 현재까지의 상태가 문제 조건을 담은 배열과같을 경우에만 먼저 check조건 감소(읽으면서 증가시켰던것)
                    }
                    stateArray[0]--; // 그러고 나서 state 감소해야함..! 먼저 state감소시키면 정확하게 checkCondition 조정불가. 
                    break;
    
                case 'C' :
                    if (stateArray[1] == checkArray[1]) {
                        checkCondition--;
                    }
                    stateArray[1]--;
                    break;
    
                case 'G' :
                    if (stateArray[2] == checkArray[2]) {
                        checkCondition--;
                    }
                    stateArray[2]--;
                    break;
    
                case 'T' :
                    if (stateArray[3] == checkArray[3]) {
                        checkCondition--;
                    }
                    stateArray[3]--;
                    break;
            }
    
        }
    }

    'Java > 코딩테스트' 카테고리의 다른 글

    백준 14503  (0) 2023.04.06
    [ DFS / BFS ] 개념 및 예제 정리  (0) 2023.04.05
    [DP] 백준 풀이 기록 JAVA (Feat. do it 알고리즘 코딩테스트)  (0) 2023.04.05
    백준 11003(Java)  (0) 2022.08.07
    백준 11659, 11660, 2018(Java)  (0) 2022.07.18
Designed by Tistory.