Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

허준혁 / 11월 2주차 / 월, 목 #325

Merged
merged 8 commits into from
Nov 11, 2023
Merged

Conversation

ComelyU
Copy link
Contributor

@ComelyU ComelyU commented Nov 7, 2023


🎈boj 14711 - 타일 뒤집기 (Easy)


🗨 해결방법 :

아래쪽, 왼쪽, 오른쪽 방향과 위쪽 방향을 따로 생각하여 풀었습니다.

📝메모 :


✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * [boj] 14711. 타일 뒤집기 (Easy)
 */
public class boj14711 {
    /**
     * N: 게임판의 크기
     */
    static int N;
    /**
     * board: 게임판
     */
    static char[][] board;
    static boolean[][] visited;
    /**
     * dr, dc: delta값. 하좌우 순서.
     */
    static int[] dr = {1, 0, 0}, dc = {0, -1, 1};
    static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        N = Integer.parseInt(br.readLine());

        board = new char[N][N];
        visited = new boolean[N][N];
        String firstLine = br.readLine();
        for(int i = 0; i < N; i++) {
            board[0][i] = firstLine.charAt(i);
            sb.append(board[0][i]);
        }
        sb.append("\n");

        solve();

        System.out.print(sb.toString());

    }

    public static void solve() {
        for(int i = 0, checkSize = N - 1; i < checkSize; i++) {
            for(int j = 0; j < N; j++) {
                if(board[i][j] == '#') {
                    for(int d = 0; d < 3; d++) {
                        int nextR = i + dr[d];
                        int nextC = j + dc[d];

                        if(!isInBoard(nextR, nextC)) {
                            continue;
                        }

                        visited[nextR][nextC] = !visited[nextR][nextC];
                    }
                }
            }

            for(int j = 0; j < N; j++) {
                board[i + 1][j] = visited[i][j] ? '#' : '.';
                sb.append(board[i + 1][j]);
            }
            sb.append("\n");
        }
    }

    public static boolean isInBoard(int r, int c) {
        return 0 <= r && r < N && 0 <= c && c < N;
    }
}


🎈boj 11037 - 중복 없는 수


🗨 해결방법 :

순열과 이분 탐색으로 풀었습니다.

📝메모 :


✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;

/**
 * [boj] 11037. 중복 없는 수
 */
public class boj11037 {
    static ArrayList<Integer> noOverlapNumList = new ArrayList<>();
    static int num, answerIdx;
    static int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    static boolean[] visited = new boolean[9];
    static StringBuilder sb = new StringBuilder();

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        for(int i = 1; i <= 9; i++) {
            makeNoOverlapNum(0, 0, i);
        }
//        System.out.println(noOverlapNumList.toString());

        String strNum = "";
        while((strNum = br.readLine()) != null && (!strNum.isEmpty())) {
//            System.out.println("strNum" + strNum);
            num = Integer.parseInt(strNum);
//            System.out.println(num);
            if(num >= 987654321) {
                sb.append(0).append("\n");
            } else {
                upperBound();
                sb.append(noOverlapNumList.get(answerIdx)).append("\n");
//                System.out.println(noOverlapNumList.get(answerIdx));
            }
        }

        System.out.print(sb.toString());
    }

    /**
     * 순열을 이용하여 중복 없는 수를 모두 구함
     * @param nowLength
     * @param nowNum
     * @param minLength
     */
    public static void makeNoOverlapNum(int nowLength, int nowNum, int minLength) {
        if(nowLength >= minLength) {
            noOverlapNumList.add(nowNum);
        } else {
            for(int i = 0; i < 9; i++) {
                if(!visited[i]) {
                    visited[i] = true;
                    makeNoOverlapNum(nowLength + 1, nowNum * 10 + numbers[i], minLength);
                    visited[i] = false;
                }
            }
        }
    }

    /**
     * upperbound를 사용하는 bianry search로 탐색.
     */
    public static void upperBound() {
        int low = 0;
        int high = noOverlapNumList.size();

        while(low <= high) {
            int mid = (low + high) >> 1;

            if(noOverlapNumList.get(mid) <= num) {
                low = mid + 1;
            } else {
                answerIdx = mid;
                high = mid - 1;
            }
        }
    }
}


🎈boj 22942 - 데이터 체커


🗨 해결방법 :

스택을 이용하여 풀었습니다.

📝메모 :


✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Stack;
import java.util.StringTokenizer;

/**
 * [boj] 22942. 데이터 체커
 */
public class boj22942 {
    /**
     * XAxisDot: 원이 x축과 접하는 점을 의미하는 클래스
     */
    static class XAxisDot implements Comparable<XAxisDot> {
        /**
         * circleSequnce: 몇 번째 원인가
         */
        int circleSequnce;
        /**
         * xCoordinate: 접점의 x좌표
         */
        int xCoordinate;
        /**
         * isLeftDot: 왼쪽 접점인가
         */
        boolean isLeftDot;

        public XAxisDot(int circleSequnce, int xCoordinate, boolean isLeftDot) {
            this.circleSequnce = circleSequnce;
            this.xCoordinate = xCoordinate;
            this.isLeftDot = isLeftDot;
        }

        @Override
        public int compareTo(XAxisDot o) {
            return Integer.compare(this.xCoordinate, o.xCoordinate);
        }

        @Override
        public String toString() {
            return "XAxisDot{" +
                    "circleSequnce=" + circleSequnce +
                    ", xCoordinate=" + xCoordinate +
                    ", isLeftDot=" + isLeftDot +
                    '}';
        }
    }
    /**
     * N: 원의 수
     */
    static int N;
    static XAxisDot[] xAxisDots;
    static Stack<XAxisDot> xAxisDotStack = new Stack<>();


    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        N = Integer.parseInt(br.readLine());

        xAxisDots = new XAxisDot[N * 2];
        for(int i = 0, idx = 0; i < N; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");

            int centerX = Integer.parseInt(st.nextToken());
            int r = Integer.parseInt(st.nextToken());

            xAxisDots[idx++] = new XAxisDot(i, centerX - r, true);
            xAxisDots[idx++] = new XAxisDot(i, centerX + r, false);
        }

        Arrays.sort(xAxisDots);

        System.out.println(check() ? "YES" : "NO");
    }

    public static boolean check() {
        for(int i = 0; i < N * 2; i++) {
            if(i != 0 && xAxisDots[i - 1].xCoordinate == xAxisDots[i].xCoordinate) {
                return false;
            }
            if(xAxisDotStack.isEmpty()) {
                xAxisDotStack.push(xAxisDots[i]);
            } else {
                if(xAxisDots[i].isLeftDot) {
                    xAxisDotStack.push(xAxisDots[i]);
                } else {
                    if(xAxisDotStack.peek().circleSequnce == xAxisDots[i].circleSequnce) {
                        xAxisDotStack.pop();
                    } else {
                        return false;
                    }
                }
//                XAxisDot nowDot = xAxisDotStack.peek();
//
//                if(nowDot.circleSequnce == xAxisDots[i].circleSequnce) { // 같은 원
//                    xAxisDotStack.pop();
//                } else {
//                    if((nowDot.isLeftDot && !xAxisDots[i].isLeftDot)) { // 두 원의 접점 발생
//                        return false;
//                    }
//                    xAxisDotStack.push(xAxisDots[i]);
//                }
            }
        }
        return true;
    }
}


🎈boj 14226 - 이모티콘


🗨 해결방법 :

bfs로 풀었습니다

📝메모 :


✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Queue;

/**
 * [boj] 14226. 이모티콘
 */
public class boj14226 {
    static class Status {
        int screenEmoticonCnt;
        int clipboardEmoticonCnt;
        int time;

        public Status(int screenEmoticonCnt, int clipboardEmoticonCnt, int time) {
            this.screenEmoticonCnt = screenEmoticonCnt;
            this.clipboardEmoticonCnt = clipboardEmoticonCnt;
            this.time = time;
        }
    }
    /**
     * S: 최종 이모티콘의 수
     */
    static int S, maxSize;
    static boolean[][] visited;
    static Queue<Status> statusQueue = new ArrayDeque<>();

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        S = Integer.parseInt(br.readLine());
        maxSize = S << 1;

        System.out.println(bfs());
    }

    public static int bfs() {
        visited = new boolean[maxSize + 1][maxSize + 1];
        visited[1][0] = true;

        statusQueue.offer(new Status(1, 0, 0));

        while(!statusQueue.isEmpty()) {
            Status now = statusQueue.poll();

            if(now.screenEmoticonCnt == S) {
                return now.time;
            }

            if(now.screenEmoticonCnt > 0 && now.screenEmoticonCnt < maxSize) {
                // 화면에 있는 이모티콘을 모두 복사해서 클립보드에 저장
                if(!visited[now.screenEmoticonCnt][now.screenEmoticonCnt]) {
                    visited[now.screenEmoticonCnt][now.screenEmoticonCnt] = true;

                    statusQueue.offer(new Status(now.screenEmoticonCnt, now.screenEmoticonCnt, now.time + 1));
                }

                // 화면에 있는 이모티콘 중 하나를 삭제
                if(!visited[now.screenEmoticonCnt - 1][now.clipboardEmoticonCnt]) {
                    visited[now.screenEmoticonCnt - 1][now.clipboardEmoticonCnt] = true;

                    statusQueue.offer(new Status(now.screenEmoticonCnt - 1, now.clipboardEmoticonCnt, now.time + 1));
                }
            }

            // 클립보드에 있는 모든 이모티콘을 화면에 붙여넣기
            if(now.clipboardEmoticonCnt > 0 && now.screenEmoticonCnt + now.clipboardEmoticonCnt < maxSize) {
                visited[now.screenEmoticonCnt + now.clipboardEmoticonCnt][now.clipboardEmoticonCnt] = true;

                statusQueue.offer(new Status(now.screenEmoticonCnt + now.clipboardEmoticonCnt, now.clipboardEmoticonCnt, now.time + 1));
            }
        }
        return -1;
    }
}


🎈boj 23829 - 인문예술탐사주간


🗨 해결방법 :

prefix sum + lower bound로 풀었습니다

📝메모 :


✔코드 :

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

/**
 * [boj] 23829. 인문예술탐사주간
 */
public class boj23829 {
    /**
     * N: 나무의 수, Q: 찍은 사진의 수, leftTreeCnt: 사진 찍은 위치보다 왼쪽에 위치한 나무의 수
     */
    static int N, Q, leftTreeCnt;
    static int[] trees;
    static long[] prefixSumArr;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        StringBuilder sb = new StringBuilder();

        N = Integer.parseInt(st.nextToken());
        Q = Integer.parseInt(st.nextToken());

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

        Arrays.sort(trees);

        prefixSum();
        while(Q-- > 0) {
            int picLocation = Integer.parseInt(br.readLine());

            lowerBound(picLocation);
//            System.out.println("AAA : " + leftTreeCnt);
            long leftSum = ((long) picLocation * leftTreeCnt) - prefixSumArr[leftTreeCnt];
            long rightSum = (prefixSumArr[N] - prefixSumArr[leftTreeCnt]) - ((long) picLocation * (N - leftTreeCnt));

            sb.append(leftSum + rightSum).append("\n");
        }

        System.out.print(sb.toString());

    }

    public static void prefixSum() {
        prefixSumArr = new long[N + 1];

        for(int i = 1; i <= N; i++) {
            prefixSumArr[i] = prefixSumArr[i - 1] + trees[i - 1];
        }
    }

    public static void lowerBound(int picLoc) {
        leftTreeCnt = -1;
        int low = 0;
        int high = N - 1;

        while(low <= high) {
            int mid = (low + high) >> 1;
            if(trees[mid] >= picLoc) {
//                System.out.println("mid : " + mid);
                leftTreeCnt = mid;
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }

        if(leftTreeCnt == -1) {
            leftTreeCnt = N;
        }
    }
}


🎈boj 25795 - 예쁜 초콜릿과 숫자놀이


🗨 해결방법 :

재귀로 풀었습니다.

📝메모 :


✔코드 :

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

/**
 * [boj] 25795. 예쁜 초콜릿과 숫자놀이
 */
public class boj25795 {
    /**
     * N: 화이트 초콜릿과 다크 초콜릿의 개별 수량,
     * a: 시작 정수, b: 화이트 초콜릿인 경우 더할 수, c: 다크 초콜릿인 경우 곱할 수
     */
    static int N, a, b, c;
    static long maxScore;
    static final int MOD = 100_000;

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

        N = Integer.parseInt(st.nextToken());
        a = Integer.parseInt(st.nextToken());
        b = Integer.parseInt(st.nextToken());
        c = Integer.parseInt(st.nextToken());

        solve(0, 0, a);

        System.out.println(maxScore);
    }

    public static void solve(int whiteCnt, int darkCnt, long score) {
        if(whiteCnt == N && darkCnt == N) {
            maxScore = Math.max(maxScore, score);
            return;
        }

        if(whiteCnt == darkCnt) {
            solve(whiteCnt + 1, darkCnt, (score + b) % MOD);
        } else if(whiteCnt > darkCnt && whiteCnt == N) {
            solve(whiteCnt, darkCnt + 1, (score * c) % MOD);
        } else if(whiteCnt > darkCnt) {
            solve(whiteCnt + 1, darkCnt, (score + b) % MOD);
            solve(whiteCnt, darkCnt + 1, (score * c) % MOD);
        }
    }
}


🎈boj 30108 - 교육적인 트리 문제


🗨 해결방법 :

우선순위 큐로 최대 힙을 구현하여 풀었습니다.

📝메모 :


✔코드 :

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

/**
 * [boj] 30108. 교육적인 트리 문제
 */
public class boj30108 {
    /**
     *
     */
    static int N;
    static PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        StringBuilder sb = new StringBuilder();

        N = Integer.parseInt(br.readLine());

//        st = new StringTokenizer(br.readLine(), " ");
        String noUseInput = br.readLine();
        st = new StringTokenizer(br.readLine(), " ");
        for(int i = 0; i < N; i++) {
            maxHeap.offer(Integer.parseInt(st.nextToken()));
        }

        Long sum = 0L;
        for(int i = 1; i <= N; i++) {
            sum += maxHeap.poll();
            sb.append(sum).append("\n");
        }

        System.out.print(sb.toString());
    }
}


🎈boj 17092 - 색칠 공부


🗨 해결방법 :

HashSet을 사용하여 풀었습니다.

📝메모 :

2차원을 1차원으로 인덱스 변환

✔코드 :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.StringTokenizer;

/**
 * [boj] 17092. 색칠 공부
 */
public class boj17092 {
    /**
     * H: 모눈종이의 행 수, W: 모눈종이의 열 수, N: 검정색 칸의 수
     */
    static int H, W, N;
    static HashSet<Long> graphPaper = new HashSet<>(), checkPoint = new HashSet<>();
//    static int[] dr = {-1, -1, -1, 0, 0, 0, 1, 1, 1}, dc = {-1, 0, 1, -1, 0, 1, -1, 0, 1};
    static int[] drdc;
    static long[] blackCount = new long[10];
    static StringBuilder sb = new StringBuilder();

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

        H = Integer.parseInt(st.nextToken());
        W = Integer.parseInt(st.nextToken());
        N = Integer.parseInt(st.nextToken());

        for(int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine(), " ");

            int r = Integer.parseInt(st.nextToken());
            int c = Integer.parseInt(st.nextToken());

            graphPaper.add((long) (r - 1) * W + c);
        }

        drdc = new int[] {-W - 1, -W, -W + 1, -1, 0, 1, W - 1, W, W + 1};
        for(long point: graphPaper) {
            for(int i = 0; i < 9; i++) {
                checkBlackCount(point, i);
            }
        }

        blackCount[0] = (long) (H - 2) * (W - 2);
        for(int i = 1; i <= 9; i++) {
            blackCount[0] -= blackCount[i];
        }

        for(long cnt: blackCount) {
            sb.append(cnt).append("\n");
        }

        System.out.print(sb.toString());
    }

    public static void checkBlackCount(long point, int idx) {
        long now = point + drdc[idx];

        if(!isPossible(now)) {
            return;
        }

        if(checkPoint.contains(now)) {
            return;
        }

        int count = 0;
        for(int i = 0; i < 9; i++) {
            long next = now + drdc[i];

            if(graphPaper.contains(next)) {
                count++;
            }
        }

        blackCount[count]++;
        checkPoint.add(now);
    }

    public static boolean isPossible(long val) {
        return W < val && val <= (long) (H - 1) * W && (val % W != 0) && (val % W != 1);
    }
}


//public class boj17092 {
//    static class Coordinate {
//        int r;
//        int c;
//
//        public Coordinate(int r, int c) {
//            this.r = r;
//            this.c = c;
//        }
//
//        @Override
//        public boolean equals(Object obj) {
//            if(obj instanceof Coordinate) {
////                return this.r == ((Coordinate) obj).r && this.c == ((Coordinate) obj).c;
//                // hashCode가 r+c인 상태에서 r값이 동일하면 c값도 동일함이 보장.
//                return this.r == ((Coordinate) obj).r;
//            } else {
//                return false;
//            }
////            return this.r == ((Coordinate) obj).r;
//        }
//
//        @Override
//        public int hashCode() {
//            return r + c;
//        }
//    }
//    /**
//     * H: 모눈종이의 행 수, W: 모눈종이의 열 수, N: 검정칸의 수
//     */
//    static int H, W, N;
//    /**
//     * graphPaper: 모눈종이
//     * checkPoint: 확인을 마친 위치
//     */
////    static HashSet<Coordinate> graphPaper = new HashSet<>(), checkPoint = new HashSet<>();
////    static LinkedHashSet<Coordinate> graphPaper = new LinkedHashSet<>(), checkPoint = new LinkedHashSet<>();
//    static LinkedHashSet<Coordinate> graphPaper, checkPoint;
//    static long[] blackCount = new long[10];
//    static int[] dr = {-1, -1, 1, 1, -1, 0, 0, 1, 0}, dc = {-1, 1, -1, 1, 0, -1, 1, 0, 0};
////    static long totalCount = 0;
//    static StringBuilder sb = new StringBuilder();
//
//    public static void main(String[] args) throws Exception {
//        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
//
//        H = Integer.parseInt(st.nextToken());
//        W = Integer.parseInt(st.nextToken());
//        N = Integer.parseInt(st.nextToken());
//
//        graphPaper = new LinkedHashSet<>(N);
//        checkPoint = new LinkedHashSet<>(N);
//        for(int i = 0; i < N; i++) {
//            st = new StringTokenizer(br.readLine(), " ");
//
//            int r = Integer.parseInt(st.nextToken());
//            int c = Integer.parseInt(st.nextToken());
//
//            graphPaper.add(new Coordinate(r, c));
//        }
//
//        for(Coordinate refPoint: graphPaper) {
//            for(int i = 0; i < 9; i++) {
//                checkBlackCount(i, refPoint);
//            }
//        }
//
//        blackCount[0] = (long) (H - 2) * (W - 2);
//        for(int i = 1; i <= 9; i++) {
//            blackCount[0] -= blackCount[i];
//        }
//
//        for(long nthCount: blackCount) {
//            sb.append(nthCount).append("\n");
//        }
//
//        System.out.print(sb.toString());
//    }
//
//    public static void checkBlackCount(int i, Coordinate refPoint) {
//        int count = 0;
//
//        Coordinate now = new Coordinate(refPoint.r + dr[i], refPoint.c + dc[i]);
//
//        if(!isExist(now.r, now.c)) {
//            return;
//        }
//
//        if(checkPoint.contains(now)) { // now의 위치가 3*3 보드의 중앙으로 하여 체크한 곳일 때
//            return;
//        }
//
//        for(int j = 0; j < 9; j++) {
//            Coordinate next = new Coordinate(now.r + dr[j], now.c + dc[j]);
//
//            if(graphPaper.contains(next)) {
//                count++;
//            }
//        }
//
////        System.out.println("AAA : " + count);
//
//        checkPoint.add(now);
////        totalCount++;
//        blackCount[count]++;
//    }
//
//    public static boolean isExist(int r, int c) {
//        return 1 < r && r < H && 1 < c && c < W;
//    }
//}

@ComelyU ComelyU changed the title 허준혁 / 11월 2주차 / 월 허준혁 / 11월 2주차 / 월, 목 Nov 9, 2023
@ComelyU ComelyU merged commit a6733eb into SSAFY-10th-Seoul17:main Nov 11, 2023
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants