Red Glitter Pointer

 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

import java.util.Stack;

class Solution {
    public int solution(int[][] board, int[] moves) {
        int answer = 0;
        Stack<Integer> stack = new Stack<>();
        for(int i = 0; i < moves.length; i++) {
            for(int j = 0; j < board.length; j++) {
                if(board[j][moves[i] - 1] > 0) { // 인형이 있을 경우에 뽑기 진행
                	// 스택에 인형이 있고, 현재 뽑은 인형이랑 동일할 경우 터트리기
                    // 아니라면 스택에 인형 넣기
                    if(!stack.isEmpty() && board[j][moves[i] - 1] == stack.peek()) {
                        answer += 2;
                        stack.pop();
                    } else {
                        stack.add(board[j][moves[i] - 1]);
                    }
                    // 인형을 뽑은 자리에 0으로 초기화
                    board[j][moves[i] - 1] = 0;
                    break;
                }
            }
        }
        return answer;
    }
}

 

느낀 점 및 정리 ✍️

1. 스택을 사용하여 뽑은 인형들을 스택에 넣고, 인형을 뽑을 때마다 스택의 가장 최상단의 인형과 일치하는지 확인, 일치한다면 인형 터트리기(answer += 2), stack.pop()

2. 아니라면 스택에 인형 넣는다

3. moves[i] - 1 을 한 이유는, 배열의 인덱스는 0부터 시작인데 크레인의 입력 값은 1부터 시작이기 때문에 크레인의 값에서 -1을 해주어야 인덱스가 맞는다

 

 

 

 

 

22862번: 가장 긴 짝수 연속한 부분 수열 (large)

수열 $S$에서 최대 $K$번 원소를 삭제한 수열에서 짝수로 이루어져 있는 연속한 부분 수열 중 가장 긴 길이를 출력한다.

www.acmicpc.net

 

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public int solution(int N, int K, int[] S) {
        int answer = 0, lt = 0, cnt = 0;
        // 오른쪽 포인터가 배열의 끝까지 갈때까지만 진행
        for(int rt = 0; rt < N; rt++) {
            if(S[rt] % 2 != 0) cnt++; // 홀수라면 삭제 횟수 증가
			// 삭제 가능한 횟수를 초과하면 왼쪽 포인터를 오른쪽으로 옮기기
            while(cnt > K) {
                if(S[lt] % 2 != 0) cnt--;
                lt++;
            }
            // rt와 lt의 간격을 계산하고, 삭제한 홀수의 개수만큼 빼주기
            answer = Math.max(answer, rt - lt + 1 - cnt);
        }
        return answer;
    }

    public static void main (String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        Main T = new Main();
        int N = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());
        int[] S = new int[N];

        st = new StringTokenizer(br.readLine());
        for(int i = 0; i < N; i++) {
            S[i] = Integer.parseInt(st.nextToken());
        }

        System.out.println(T.solution(N, K, S));
    }

}

 

 

느낀 점 및 정리 ✍️

1. 코테 대비로 요즘 알고리즘 문제 풀 때 solution 메소드를 따로 생성하여 풀고 있다

2. 투 포인터 알고리즘을 활용하여 풀었다

 

 

 

 

 

 

SELECT ROUND(long_w, 4)
FROM station
WHERE lat_n < 137.2345
ORDER BY lat_n DESC
LIMIT 1

 

 

느낀 점 및 정리✍️

1. largest Northern Latitude 중에 가장 큰 값 => DESC 정렬하여 LIMIT 1로 구했다

2. 137.2345보다 작은 값이어야하기 때문에 => WHERE절 사용하여 걸러냄

3. 소수점 4자리까지 반올림 한 값을 출력 => ROUND 사용

 

 

 

 

 

 

 

SELECT name
FROM students
WHERE marks > 75
ORDER BY RIGHT(name, 3), id

 

 

느낀 점 및 정리 ✍️

1. "Order your output by the last three characters of each name" => RIGHT(name, 3) 을 사용해서 이름의 가장 오른쪽에 있는 문자 3개를 추출하여 정렬했다.

2. "names ending in the same last three characters, secondary sort them by ascending ID" => 문자 3가지가 동일할 경우 id 오름차순 정렬

 

 

 

 

 

 

15831번: 준표의 조약돌

첫 줄에 조약돌의 총 개수 N, 준표가 원하는 검은 조약돌의 최대개수 B와 하얀 조약돌의 최소개수 W가 주어진다. 둘째 줄에는 N개의 조약돌의 정보가 한 줄로 주어진다. i번째 문자가 B라면 i번 조

www.acmicpc.net

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public int solution(int N, int B, int W, char[] arr) {
        int lt = 0, rt = 0; // 왼쪽 포인터, 오른쪽 포인터
        int max = 0;
        int[] stone = new int[2]; // stone[0] = W의 개수, stone[1] = B의 개수

        while(rt < N) {
            // 현재 rt 위치의 돌 추가
            if(arr[rt] == 'B') stone[1]++;
            else stone[0]++;

            // B의 개수가 문제에서 입력받은 B개를 넘어서면
            // 가장 왼쪽에 있던 돌을 빼면서 왼쪽 포인터를 증가
            if(B < stone[1]) {
                if(arr[lt] == 'B') stone[1]--;
                else stone[0]--;
                lt++;
            }
            // W돌의 개수가 입력받은 W개 이상이 되면 최댓값 갱신 
            if(stone[0] >= W) max = Math.max(max, rt - lt + 1);
            rt++; // 오른쪽 포인터 이동
        }
        return max;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        Main T = new Main();

        int N = Integer.parseInt(st.nextToken());
        int B = Integer.parseInt(st.nextToken());
        int W = Integer.parseInt(st.nextToken());

        char[] arr = br.readLine().toCharArray();

        System.out.println(T.solution(N, B, W, arr));
    }
}

 

 

느낀 점 및 정리 ✍️

1. 코딩테스트 대비하고자 프로그래머스 제출 형식에 맞춰 solution 메소드를 생성하여 코드를 작성했다.

2. 첫 제출에서는 14%에서 틀렸습니다가 떴었고 두 번째 제출에서 맞았다. 왜 처음부터 완벽하게 못맞추는거니............!!!!!!!!!!!!!!!!!!! 주어진 테스트 케이스 2개만 통과하면 그냥 제출해보는 안좋은.. 습관이 .. ^^ ㅎ 코테때 시간도 촉박할텐데 걱정이당 😓

3. 오른쪽 포인터를 증가시키면서 해당 자리에 있는 돌의 개수를 세어주었다. 그러다가 입력받은 B 숫자보다 검정돌이 많아질 경우, 가장 왼쪽에 있는 돌을 하나 빼고 왼쪽 포인터의 위치를 우측으로 옮겨준다. 가지고 있는 흰색 돌의 개수가 입력받은 W 숫자 이상일 경우, 최댓값을 갱신해주는 방식으로 풀었다.

 

 

 

설계 시간: 10분

풀이 시간: 32분

디버깅 시간: 20분

 

 

15961번: 회전 초밥

첫 번째 줄에는 회전 초밥 벨트에 놓인 접시의 수 N, 초밥의 가짓수 d, 연속해서 먹는 접시의 수 k, 쿠폰 번호 c가 각각 하나의 빈 칸을 사이에 두고 주어진다. 단, 2 ≤ N ≤ 3,000,000, 2 ≤ d ≤ 3,000, 2

www.acmicpc.net

 

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int d = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());
        int c = Integer.parseInt(st.nextToken());

        int[] sushi = new int[N];
        for(int i = 0; i < N; i++) {
            sushi[i] = Integer.parseInt(br.readLine());
        }

        Map<Integer, Integer> map = new HashMap<>();
        map.put(c, 1);
        for(int i = 0; i < k; i++) {
            map.put(sushi[i], map.getOrDefault(sushi[i], 0) + 1);
        }
        int max = map.size();
        for(int i = k; i < N + k; i++) {
            map.put(sushi[i % N], map.getOrDefault(sushi[i % N], 0) + 1);
            map.put(sushi[(i - k) % N], map.getOrDefault(sushi[(i - k) % N], 0) - 1);
            if(map.get(sushi[i - k]) == 0) {
                map.remove(sushi[i - k]);
            }
            max = Math.max(max, map.size());
        }
        System.out.println(max);
    }
}

 

느낀 점 및 정리 ✍️

1. 처음 설계했을 땐 "회전"(배열의 시작과 끝이 이어져있음)의 특성을 고려하지 않아서 제출 후 10퍼센트 정도에서 틀렸다는 문구가 출력됐었다. 슬라이딩 윈도우 알고리즘을 사용해서 Sysout으로 한 문장씩 아무리 찍어봐도 왜 틀린건지 알 수가 없었는데, 생각해보니 N번만 돌릴게 아니라 N + k - 1까지 돌려서 확인해야했다. 

2. 배열의 인덱스를 계산할 때, 크기를 넘어가지 않도록 i % N 을 사용하여 배열의 시작으로 다시 돌아오도록 작성했다.

3. 설계할 때부터 회전을 고려하지 못했어서 ㅠ ,, 이건 많은 문제들을 접하다보면 자연스럽게 고려하게 되겠지.. 싶다...! 파이팅

 

 

 

 

 

 

1735번: 분수 합

첫째 줄과 둘째 줄에, 각 분수의 분자와 분모를 뜻하는 두 개의 자연수가 순서대로 주어진다. 입력되는 네 자연수는 모두 30,000 이하이다.

www.acmicpc.net

 

 

 

작성한 코드 👇

import java.io.IOException;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = sc.nextInt();
        int c = sc.nextInt();
        int d = sc.nextInt();

        int deno = b * d;
        int num = (a * d) + (b * c);

        int answer = gdc(Math.max(deno, num), Math.min(deno, num));
        System.out.println(num / answer + " " + deno / answer);
    }

    static int gdc(int a, int b) {
        if(b == 0) return a;
        return gdc(b, a % b);
    }
}

 

 

느낀 점 및 정리 ✍️

1. 유클리드 호제법 알고리즘으로 풀었다. 최대공약수 최소공배수 구해야 할 때 아주 편하다

 

 

 

 

💡 유클리드 호제법이란? 아래 링크 참고 ! 

 

유클리드 호제법 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 유클리드 호제법(-互除法, Euclidean algorithm) 또는 유클리드 알고리즘은 2개의 자연수 또는 정식(整式)의 최대공약수를 구하는 알고리즘의 하나이다. 호제법이란

ko.wikipedia.org

 

 

풀이 : 7분

 

 

5218번: 알파벳 거리

첫째 줄에 테스트 케이스의 수 (< 100)가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 두 단어가 공백으로 구분되어져 있다. 단어의 길이는 4보다 크거나 같고, 20보다 작거나 같으며, 알

www.acmicpc.net

 

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int tc = Integer.parseInt(br.readLine());
        StringBuilder sb = new StringBuilder();

        while(tc-- > 0) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            char[] arr1 = st.nextToken().toCharArray(); // 문자열을 문자로 쪼개서 배열에 저장
            char[] arr2 = st.nextToken().toCharArray(); // 상동
            sb.append("Distances:");

            for(int i = 0; i < arr1.length; i++) {
                if(arr1[i] <= arr2[i]) sb.append(" ").append((arr2[i] - 48) - (arr1[i] - 48));
                 else sb.append(" ").append((arr2[i] - 22) - (arr1[i] - 48));
            }
            sb.append("\n");
        }
        System.out.println(sb);
    }
}

 

1. 받은 문자열을 문자로 쪼개서 배열에 저장한다. ABCD -> [A][B][C][D]

2. for문 돌면서 arr1과 arr2 동일 인덱스에 들어있는 문자의 거리를 비교해서 차이 값을 stringBuilder에 저장해준다.

 

느낀점 및 정리 ✍️

오늘은 알고리즘 개념 학습 하느라 백준 문제는 스트릭 채우기 용으로 쉬운 문제 풀었다... ㅎㅎ ;;

 

 

+ Recent posts

loading