Problem Solving (67)

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/131697

 

코드

select MAX(price) as MAX_PRICE
from product

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/164673

 

풀이

첫번째 방법 : 조인

두번째 방법 : 테이블 2개 두고 where로 조건 걸기

 

어떤 것이 더 효율적인 방법인지 생각해보고 싶다

조인의 경우는 where절에서 필터링을 걸기 때문에 조인을 수행하고 난 뒤면 데이터의 크기가 너무 커지지 않는지 궁금하다.

그리고 두번째 방법을 쓰는 경우 where에서 board_id가 같은 것만 선택하는 것 깜빡하지 않기!!

 

코드

# 조인
select
    TITLE, 
    b.BOARD_ID, 
    REPLY_ID, 
    r.WRITER_ID, 
    r.CONTENTS, 
    DATE_FORMAT(r.CREATED_DATE, "%Y-%m-%d") as CREATED_DATE
from USED_GOODS_BOARD as b join USED_GOODS_REPLY as r
on b.BOARD_ID = r.BOARD_ID
where YEAR(b.CREATED_DATE) = 2022 and MONTH(b.CREATED_DATE) = 10
order by r.CREATED_DATE, TITLE;

# where
select 
    title, 
    b.board_id, 
    reply_id, 
    r.writer_id, 
    r.contents, 
    date_format(r.created_date, "%Y-%m-%d") as CREATED_DATE
from used_goods_board as b, used_goods_reply as r
where b.board_id = r.board_id
and date_format(b.created_date, "%Y-%m") = '2022-10'
order by r.created_date, title;

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/133025

 

풀이

두가지 방법으로 풀었다.

첫번째는 서브쿼리를 사용하였고, 두번째는 join을 사용했다

 

코드

# 서브쿼리
select flavor
from first_half
where total_order > 3000 and flavor in (
    select flavor
    from icecream_info
    where ingredient_type = 'fruit_based'
)
order by total_order desc;

# 조인
select first_half.flavor
from first_half join icecream_info
on first_half.flavor = icecream_info.flavor
where total_order > 3000 and ingredient_type = 'fruit_based'
order by total_order desc;

 

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/131120

 

풀이

DATE 타입을 출력하면 1992-03-16 00:00:00으로 나오기 때문에 DATE_FORMAT(DATE_OF_BIRTH, "%Y-%m-%d") as DATE_OF_BIRTH를 사용했다.

%Y 4자리 연도 %y 2자리 연도
%M 영어 월 %m 2자리 월
%D 일+th %d 2자리 일

DATE 타입에서 월만 가져오려면 MONTH(컬럼명)을 사용한다. 이외에 YEAR(대상), MONTH(대상), DAY() 아니면 DAYOFMONTH()가 있다.

 

코드

SELECT MEMBER_ID, MEMBER_NAME, GENDER, DATE_FORMAT(DATE_OF_BIRTH, "%Y-%m-%d") as DATE_OF_BIRTH
FROM MEMBER_PROFILE
WHERE GENDER = 'W' 
    and MONTH(DATE_OF_BIRTH) = 3 
    and TLNO is not null
ORDER BY MEMBER_ID;

문제 링크

https://www.acmicpc.net/problem/1018

접근 방법

M,N의 크기에서 8*8로 정사각형을 탐색한다.

8*8 정사각형이 만들어지면 그 안에서 WBWBWB, BWBWBW로 시작하는 경우를 생각하여 일치하지 않는 사각형의 개수를 센다.

WBWBWB로 시작했으면 다음 행은 BWBWBW로 탐색해야 하기 때문에, 현재 행이 홀수인지 짝수인지에 따라서 어떤 순서와 비교해야 하는지 설정했다.

또한, 현재 카운트가 최소로 칠해야 하는 사각형의 수를 넘었다면 더이상 탐색할 필요가 없기 때문에 return했다.

코드

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));
        StringTokenizer tokens = new StringTokenizer(br.readLine());

        int M = Integer.parseInt(tokens.nextToken()); //행
        int N = Integer.parseInt(tokens.nextToken()); //열

        char[][] map = new char[M][N];
        for (int i = 0; i < M; i++) {
            map[i] = br.readLine().toCharArray();
        }

        //8 * 8로 만들 수 있는 정사각형만큼 반복
        int row = M - 8 + 1;
        int col = N - 8 + 1;
        int res = Integer.MAX_VALUE;

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                res = checkArea(i, j, map, res);
            }
        }
        System.out.println(res);

    }

    private static int checkArea(int row, int col, char[][] map, int res) {
        char[] W = {'W', 'B', 'W', 'B', 'W', 'B', 'W', 'B'};
        char[] B = {'B', 'W', 'B', 'W', 'B', 'W', 'B', 'W'};

        //현재 row행 col열에서 시작하여 8*8의 정사각형 확인
        int wcnt = 0; //W로 시작하는 경우 색칠할 사각형 수
        int bcnt = 0; //B로 시작하는 경우 색칠할 사각형 수

        //해당 정사각형에서 색이 일치하지 않는 사각형 개수 확인
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                char now = map[row + i][col + j];
                if(i%2==0){
                    if(now!=W[j]) wcnt++;
                    if(now!=B[j]) bcnt++;
                }else{
                    if(now!=B[j]) wcnt++;
                    if(now!=W[j]) bcnt++;
                }
                if(wcnt > res && bcnt > res)
                    return res;
            }
        }
        return Math.min(res, Math.min(wcnt, bcnt));
    }
}

'Problem Solving > BOJ' 카테고리의 다른 글

[백준 Java] 13458 시험 감독  (0) 2023.06.01
[백준 Java] 1316 그룹 단어 체커  (0) 2023.05.25
[백준 Java] 1439 뒤집기  (0) 2023.04.18
[백준 Java] 7562 나이트의 이동  (0) 2023.04.09
[백준 Java] 4673 셀프 넘버  (0) 2023.03.24

문제 링크

https://www.codetree.ai/training-field/search/a-train-that-goes-together/description?page=1&pageSize=20&username= 

 

접근 방법

위치가 증가하는 순서로 주어졌기 때문에 배열의 뒤에서부터 탐색한다.

열차의 속도가 같거나 작은 경우는 따라잡지 못하고, 큰 경우에는 따라잡을 수 있다.

반복문을 돌면서 가장 끝 위치의 속도를 저장하고 이 속도보다 작거나 같은 경우 만날 수 없기 때문에 결과값 증가, 열차의 속도를 현재 배열 값으로 갱신한다.

 

코드

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));
        StringTokenizer tokens;

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

        int[] arr = new int[N];

        for (int i = 0; i < N; i++) {
            tokens = new StringTokenizer(br.readLine());
            Integer.parseInt(tokens.nextToken());
            int speed = Integer.parseInt(tokens.nextToken());

            arr[i] = speed;
        }

        int res = 1;
        int min = arr[N - 1];

        for (int i = N - 2; i >= 0; i--) {
            if(arr[i] <= min){
                res++;
                min = arr[i];
            }
        }

        System.out.println(res);

    }
}

문제 링크

https://www.codetree.ai/training-field/search/milk-production-competition/description?page=3&pageSize=20&username=

 

접근 방법

  • 100일 만큼의 크기인 days 배열에 소의 이름과 등락값 저장
  • 100일만큼 반복문을 돌면서 우유의 등락값 계산
  • 우유의 최대값을 계산하고 임시 전광판 배열인 temp에서 최대값으로 우유를 생산한 소의 전광판만 1로 표시해줌
  • 이전 전광판과 비교해서 달라졌다면 res++
  • 전광판 갱신

 

코드

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

public class Main_우유생산량경쟁 {

    static final StringB= "Bessie";
    static final StringE= "Elsie";
    static final StringM= "Mildred";

    static class Cows{
        String name;
        int upDown;

        public Cows(String name, int upDown) {
            this.name = name;
            this.upDown = upDown;
        }
    }

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

        int N = Integer.parseInt(br.readLine());
        Cows[] days = new Cows[101];

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

            int day = Integer.parseInt(tokens.nextToken());
            String cow = tokens.nextToken();
            int upDown = Integer.parseInt(tokens.nextToken());

            days[day] = new Cows(cow, upDown);
        }

        //가장 처음 날짜는 7갤런씩, 3마리 모두 전광판에 이름을 올림
        int res = 0;
        int[] score = new int[]{7, 7, 7};
        int[] prev = new int[]{1, 1, 1};

        for (int i = 0; i <= 100; i++) {
            if(days[i] == null) continue;

            //우유 등락 계산
            if(days[i].name.equals(B)){
                score[0] += days[i].upDown;
            } else if (days[i].name.equals(E)) {
                score[1] += days[i].upDown;
            }else {
                score[2] += days[i].upDown;
            }

            //최대값 구하기
            int max = Math.max(score[0], Math.max(score[1], score[2]));

            //전광판에 올라갈 최대값만 저장
            int[] temp = new int[3];
            for (int j = 0; j < 3; j++) { //최대값만 저장
                if(score[j] == max) temp[j] = 1;
            }

            //이전 전광판이랑 비교해서 달라졌는지 확인
            boolean flag = false;
            for (int j = 0; j < 3; j++) {
                if(prev[j] != temp[j]) flag = true;
            }
            if(flag) res++;

            //전광판 갱신
            prev = Arrays.copyOf(temp, 3);
        }
        System.out.println(res);
    }
}

문제 링크

https://www.acmicpc.net/problem/1439

 

접근 방법

0이 연속되는 횟수와, 1이 연속되는 횟수를 구해서 적은 값을 선택한다

 

코드

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

public class Main_1439_뒤집기 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String num = br.readLine();

        //0과 1이 연속되지 않는 영역 개수 구함

        int prev = num.charAt(0) - '0'; //처음 값

        //처음 영역 설정
        int zero = prev == 0 ? 1 : 0;
        int one = prev == 1 ? 1 : 0;

        for (int i = 1; i < num.length(); i++) {
            int cur = num.charAt(i) - '0';
            if (prev != cur) {
                prev = cur;
                //현재 들어온 값이 0인지 1인지에 따라 영역 선택
                zero += cur == 0 ? 1 : 0;
                one += cur == 1 ? 1 : 0;
            }
        }

        System.out.println(Math.min(zero, one));
    }
}

문제 링크

https://www.codetree.ai/training-field/search/specific-alphabet-of-two-words/submissions?page=3&pageSize=20&username=

 

접근 방법

한 행에 대해서 양 옆의 문자 중 서로 다른 단어가 나오면 그 단어의 카운트를 집계, 같은 단어가 나온다면 가장 많이 나온 횟수를 갱신하는 것이었다.

문제 이해하는데 시간이 오래 걸려서 스터디원의 도움을 받았다.

fox box의 경우는 f, b 경우에는 겹치지 않기 때문에 1을 추가. o와 x는 둘 다 최대 1번씩 나타나기 때문에 1씩 갱신해준다

bus car의 경우에는 b는 한번 등장했기에 위에서 +1을 해줘서 총 2가 되고, 나머지의 경우도 1로 갱신이 된다.

코드

import java.io.*;
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 T = Integer.parseInt(br.readLine());

        int[] res = new int[26];
        int[] cnt1, cnt2;

        String left, right;

        for (int i = 0; i < T; i++) {
            StringTokenizer tokens = new StringTokenizer(br.readLine());
            left = tokens.nextToken();
            right = tokens.nextToken();

            cnt1 = new int[26];
            cnt2 = new int[26];

            for (int j = 0; j < left.length(); j++) {
                cnt1[left.charAt(j)-'a']++;
            }
            for (int j = 0; j < right.length(); j++) {
                cnt2[right.charAt(j)-'a']++;
            }

            for (int j = 0; j < 26; j++) {
                res[j] += Math.max(cnt1[j], cnt2[j]);
            }

        }

        for (int i = 0; i < 26; i++) {
            bw.write(res[i]+"\n");
        }
        bw.flush();
        bw.close();

    }
}

'Problem Solving > CodeTree' 카테고리의 다른 글

[CodeTree Java] 함께가는 열차  (0) 2023.04.25
[CodeTree Java] 우유 생산량 경쟁  (0) 2023.04.23
[CodeTree Java] 수의 곱셈  (0) 2023.04.17
[CodeTree Java] 코드트리 빵  (0) 2023.03.30
[Codetree Java] 꼬리잡기놀이  (0) 2023.03.22

문제 링크

https://www.codetree.ai/training-field/search/specific-alphabet-of-two-words/description?page=1&pageSize=20&username=

 

접근 방법

a, b, c와 세 수를 각각 곱한 값 7개를 만든다

리스트에 담아 큰 수 먼저 정렬, 그 다음으로 홀수를 정렬

정렬을 2번 하는 것이 비효율적이라 생각이 들었다.

스터디원의 얘기를 들어보니 홀수가 없다면 전부 곱하고, 홀수가 있다면 홀수만 계산하는 방법을 선택했다고 한다.

 

코드

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

public class Main_수의곱셈 {

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

        StringTokenizer tokens = new StringTokenizer(br.readLine());
        int a = Integer.parseInt(tokens.nextToken());
        int b = Integer.parseInt(tokens.nextToken());
        int c = Integer.parseInt(tokens.nextToken());

        ArrayList<Integer> list = new ArrayList<>();
        list.add(a);
        list.add(b);
        list.add(c);
        list.add(a * b);
        list.add(a * c);
        list.add(b * c);
        list.add(a * b * c);

        //큰 수 정렬
        Collections.sort(list, Collections.reverseOrder());

        //홀수 정렬
        Collections.sort(list, ((x, y) ->{
            if(x%2==1 && y%2==0){
                return x-y;
            }
            return y-x;
        }));

        System.out.println(list.get(0));

    }

}
1 2 3 4 5 6 7