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

 

1639번: 행운의 티켓

첫째 줄에 문자열 S가 주어진다. 문자열 S는 1보다 크거나 같고, 9보다 작거나 같은 수로만 이루어져 있고, 길이는 50보다 작거나 같은 자연수이다.

www.acmicpc.net

 

[난이도]

- Silver 4

 

[알고리즘]

- 구현

- 부르트 포스

 

[코드]

import java.io.*;
import java.util.*;

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

        String S = br.readLine();

        int N = 0;
        int answer = 0;
        for (int i = 1; i <= S.length() / 2; i++) { // (S의 길이 / 2)만큼 반복
            N = i * 2; // N은 2의배수로 증가함
            for (int j = 0; j < S.length() - N + 1; j++) { // (S의 길이 - N + 1)만큼 반복
                String tmp = S.substring(j, j + N); // 문자열을 j부터 j+N 만큼만 추출
                if (StringSum(tmp.substring(0, N / 2)) == StringSum(tmp.substring(N / 2))) { // 각 자리수를 더한 값이 같다면 true
                    answer = N; // answer 는 현재 확인하는 문자열의 길이 N
                    break; // 이미 answer를 찾았다면 더이상 할 필요가 없기 때문에 break;
                }
            }
        }
        System.out.println(answer);

        br.close();
    }

    static int StringSum(String s) { // 각 자리수를 더한 값을 반환
        int sum = 0;
        for (int i = 0; i < s.length(); i++) {
            sum += s.charAt(i) - '0';
        }
        return sum;
    }
}

 

[풀이]

부르트 포스 문제인줄알고 풀었지만 풀다보니 그냥 구현문제 같다. break로 반복문을 탈출하기 때문에 부르트포스 같지 않다.

1. 입력받은 (문자열의 길이 / 2) 만큼 반복한다. 문자열을 2N만큼 잘라서 확인하기 때문에 이렇게 제한을 두지 않으면 인덱스를 넘어가 오류가 발생한다.

2. 문자열을 2N만큼 잘라서 확인 후 좌, 우를 나눠 각 자리수의 합을 구한다. 좌, 우의 합이 같을 경우 answer을 N으로 초기화해준다.

 

다 풀고보니 시작을 2부터시작해 2, 4, 6, 8 ... 이런식으로 하는것보다 큰 수부터 ... 8, 6, 4, 2 이렇게 푸는게 시간이 더 적게 걸릴것 같다.

 

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

 

1544번: 사이클 단어

사이클 단어는 어떤 단어를 원형 모양으로 차례대로 쓴 것이다. 따라서, 어떤 단어를 이렇게 쓴 후에 임의의 단어를 고른다. 그 후에 시계방향으로 차례대로 읽으면 그 것이 단어가 된다. 만약에

www.acmicpc.net

 

 

[난이도]

- Silver 4

 

[알고리즘]

- 부르트 포스

 

[정답 코드]

import org.w3c.dom.html.HTMLParagraphElement;

import java.io.*;
import java.util.*;

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

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

        List<String> list = new ArrayList<>();
        
        for (int i = 0; i < N; i++) {
            list.add(br.readLine());
        }

        for (int i = 0; i < N; i++) {
            String tmp1 = list.get(i);
            for (int j = i + 1; j < N; j++) {
                if (tmp1.length() == list.get(j).length()) {
                    String tmp2 = list.get(j) + list.get(j);
                    if (tmp2.contains(tmp1)) {
                        list.remove(j);
                        N--;
                        j--;
                    }
                }
            }
        }
        System.out.println(N);

        bw.flush();
        bw.close();
        br.close();
    }
}

 

[풀이]

예를들어 turepic이라는 단어를 2번연속 적으면 turepicturepic 이라는 단어가 만들어 지는데, 이 문자열안에 picture라는 단어가 존재하는지 검사하는 방법을 사용했다. 

 

1. 배열이 아닌 ArrsyList에 입력값을 받아준다.

2. 검사할 단어와 비교하려는 단어의 길이가 같다면 검사를 해준다.

3. 검사 결과 사이클 단어가 맞다면 비교한 단어를 list에서 제거해준다.

  • 그냥 제거해주면 list의 인덱스가 한칸씩 밀리기 때문에 j--도 같이 해준다.
  • list를 하나 지운것이기 때문에 N--도 해준다. N--를 하지않는다면 list 인덱스밖을 검사하려고 시도하기 때문에 오류가 발생한다. 

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

 

7568번: 덩치

우리는 사람의 덩치를 키와 몸무게, 이 두 개의 값으로 표현하여 그 등수를 매겨보려고 한다. 어떤 사람의 몸무게가 x kg이고 키가 y cm라면 이 사람의 덩치는 (x, y)로 표시된다. 두 사람 A 와 B의 덩

www.acmicpc.net

 

[난이도]

- Silver 5

 

[알고리즘]

-부르트 포스

 

[정답코드]

import org.w3c.dom.html.HTMLParagraphElement;

import java.io.*;
import java.util.*;

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

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

        for (int i = 0; i < N; i++) {
            int rank = 1;

            for (int j = 0; j < N; j++) {
                if (i != j) { // 본인 제외
                    if (arr[i][0] < arr[j][0] && arr[i][1] < arr[j][1]) { // 다른 사람과 키와 몸무게를 비교, 둘다 작을경우
                        rank++; // rank를 1씩 증가
                    }
                }
            }
            bw.write(rank + " ");
        }
        bw.flush();
        bw.close();
        br.close();
    }
}

 

[풀이]

1. 다른 사람과 키와 몸무게를 비교해 두 값 모두 적다면 rank를 1씩 늘린다.

2. 비교가 끝나고 난 후의 rank를 출력해준다.

마커 인터페이스 : 아무 메서드도 담고 있지 않고, 자기 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스.

// 마크 인터페이스
public interface MarkerInterface {
    // 메서드나 상수를 정의하지 않음
}

// 위의 마크 인터페이스를 구현하는 클래스
public class MyClass implements MarkerInterface {
    // 클래스의 구현
}

 

마커 애너테이션 : 단순히 존재 여부로 정보를 제공하는 애너테이션.

 

마커 인터페이스가 마커 애너테이션보다 나은점 : 

1. 마커 인터페이스는 타입이기 때문에 애너테이션을 사용했다면 런타임에야 발견될 오류를 컴파일타임에 잡을 수 있다.

2. 적용 대상을 더 정밀하게 지정할 수 있다.

 

@Target : 해당 애너테이션이 적용될 수 있는 대상을 지정하는 데 사용. 

  • ElementType.TYPE: 클래스, 인터페이스, 열거형 등의 타입
  • ElementType.FIELD: 필드
  • ElementType.METHOD: 메서드
  • ElementType.PARAMETER: 매개변수
  • ElementType.CONSTRUCTOR: 생성자
  • ... 기타
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Entity {
    // 애너테이션의 속성 및 메서드를 정의할 수 있습니다.
}

@Entity
class MyClass {
    // MyClass 클래스에 적용되는 애너테이션입니다.
}

이 코드에서 @Entity는 마커 애너테이션이다. @Target(ElementType.TYPE)으로 설정되어 있으므로 이 애너테이션은 클래스에만 적용된다. 따라서 @Entity 애너테이션이 있는 클래스는 엔티티 클래스임을 나타내는 역할을 한다.

 

 

반대로 마커 애너테이션이 마커 인터페이스보다 나은 점 : 

1. 거대한 애너테이션 시스템의 지원을 받는다는 점.

  • 애너테이션을 적극 활용하는 프레임워크에서는 마커 애너테이션을 쓰는 쪽이 일관성을 지키는데 유리

 

정의하려는 것이 타입일때는 마커 인터페이스를 사용한 예시 : 

// 마커 인터페이스
interface MarkerInterface {
    // 아무 메서드도 정의하지 않음
}

// 마커 인터페이스를 구현한 클래스
class MyClass implements MarkerInterface {
    // MyClass의 구현
}

// 마커 인터페이스를 사용하는 메서드
public void process(Object obj) {
    if (obj instanceof MarkerInterface) {
        // obj가 MarkerInterface를 구현한 객체인 경우에만 처리
        // 해당 객체가 특정한 속성이나 동작을 가지고 있다고 가정
        System.out.println("Processing object...");
    } else {
        System.out.println("Object cannot be processed.");
    }
}

마커 인터페이스는 아무 메서드도 정의하지 않고, 단지 해당 인터페이스를 구현한 클래스가 특정한 속성이나 동작을 가지고 있다는 것을 나타낸다. 이 코드에서 process메서드는 'Object'를 파라미터로 받아 해당 객체가 MarkerInterface를 구현한 경우에만 처리한다는 것을 보여준다. 따라서 MarkerInterface는 타입으로 사용되어 해당 조건을 나타내는 역할을 하고 있다.

 

 

핵심 정리 : 마커 인터페이스와 마커 애너테이션은 각자의 쓰임이 있다. 새로 추가하는 메서드 없이 단지 타입 정의가 목적이라면 마커 인터페이스를 선택하자. 클래스나 인터페이스 외의 프로그램 요소에 마킹해야 하거나, 애너테이션을 적극 활용하는 프레임워크의 일부로 그 마커를 편입시키고자 한다면 마커 애너테이션이 올바른 선택이다. 적용 대상이 ElementType.TYPE인 마커 애너테이션을 작성하고 있다면, 잠시 여유를 갖고 정말 애너테이션으로 구현하는 게 옳은지, 혹은 마커 인터페이스가 낫지는 않을지 곰곰이 생각해보자.

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

 

1018번: 체스판 다시 칠하기

첫째 줄에 N과 M이 주어진다. N과 M은 8보다 크거나 같고, 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 보드의 각 행의 상태가 주어진다. B는 검은색이며, W는 흰색이다.

www.acmicpc.net

[난이도]

- Silver 4

 

[알고리즘]

- 부르트 포스

 

[정답 코드]

import org.w3c.dom.html.HTMLParagraphElement;

import java.io.*;
import java.util.*;

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

        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        arr = new char[N][M];

        for (int i = 0; i < N; i++) {
            String input = br.readLine();
            for (int j = 0; j < M; j++) {
                arr[i][j] = input.charAt(j);
            }
        }

        int answer = Integer.MAX_VALUE;
        for (int i = 0; i <= N - 8; i++) {
            for (int j = 0; j <= M - 8; j++) {
                answer = Math.min(answer, Math.min(startWhite(i, j), startBlack(i, j)));
            }
        }
        System.out.println(answer);

    }

    static int startWhite(int x, int y) {
        int sum = 0;
        for (int i = x; i < x+8; i++) {
            for (int j = y; j < y+8; j++) {
                if (i % 2 == 0 && j % 2 == 0) {
                    if (arr[i][j] != 'W') {
                        sum++;
                    }
                } else if (i % 2 != 0 && j % 2 == 0) {
                    if (arr[i][j] != 'B') {
                        sum++;
                    }
                } else if (i % 2 == 0 && j % 2 != 0) {
                    if (arr[i][j] != 'B') {
                        sum++;
                    }
                } else {
                    if (arr[i][j] != 'W') {
                        sum++;
                    }
                }
            }
        }

        return sum;
    }

    static int startBlack(int x, int y) {
        int sum = 0;
        for (int i = x; i < x+8; i++) {
            for (int j = y; j < y+8; j++) {
                if (i % 2 == 0 && j % 2 == 0) {
                    if (arr[i][j] != 'B') {
                        sum++;
                    }
                } else if (i % 2 != 0 && j % 2 == 0) {
                    if (arr[i][j] != 'W') {
                        sum++;
                    }
                } else if (i % 2 == 0 && j % 2 != 0) {
                    if (arr[i][j] != 'W') {
                        sum++;
                    }
                } else {
                    if (arr[i][j] != 'B') {
                        sum++;
                    }
                }
            }
        }

        return sum;
    }
}

 

[풀이]

처음엔 2차원 그래프가 나오고 문제흐름상 dfs나 bfs와 4방탐색을 활용하면 풀 수 있겠다! 라고생각했었다. 그런데 풀다보니 그렇게 풀면 코드가 더 짧아지고 시간이 더 짧게 걸릴수는 있겠지만 진짜 부르트하게 풀어도 풀리겠는데? 라는생각이 들어 다른방식으로 풀었다.

 

1. 입력받은 값중 나올 수 있는 보드판들의 시작위치를 i, j로 설정한다.

2. 시작위치가 W로 시작할 때와 B로 시작할 때 두가지 경우를 모두 확인해주어야 한다.

3. 각 말이 놓여야 하는 색과 다른색이 있을경우 sum을 1씩 증가시켜 새로칠하는 경우만 체크해준 후 반환해준다.

4. 두값중에 더 작은값을 Math.min(startWhite(i, j), startBlack(i, j)) 로 찾는다. 그리고 원래 알고있는 최솟값과 새로찾은 최소값을 비교해 정답을 찾는다.

 

 

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

백준 1544: 사이클 단어[JAVA]  (0) 2024.04.12
백준 7568: 덩치[JAVA]  (0) 2024.04.12
백준 2057: 팩토리얼 분해[JAVA]  (0) 2024.04.10
백준 1476: 날짜 계산[JAVA]  (0) 2024.04.09
백준 1543: 문서 검색[JAVA]  (0) 2024.04.09

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

 

2057번: 팩토리얼 분해

음 아닌 정수 N이 주어졌을 때, 이 수를 서로 다른 정수 M(M ≥ 1)개의 팩토리얼의 합으로 나타낼 수 있는지 알아내는 프로그램을 작성하시오. 예를 들어 2=0!+1!로 나타낼 수 있지만, 5는 이와 같은

www.acmicpc.net

 

[레벨]

- Silver 5

 

[알고리즘]

- 부르트 포스

- 수학

 

[정답 코드]

import java.io.*;
import java.util.*;

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

        long N = Long.parseLong(br.readLine());
        long[] arr = new long[21];
        if (N == 0) {
            System.out.println("NO");
            return;
        }

        arr[0] = 1L;
        for (int i = 1; i <= 20; i++) {
            arr[i] = arr[i-1] * i;
        }

        for (int i = 20; i >= 0; i--) {
            if (N >= arr[i]) {
                N -= arr[i];
            }
        }

        if (N == 0) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }
    }
}

 

[풀이]

N의 범위가 20! 까지이기 때문에 전체적으로 long 으로 초기화해준다.

N이 0일 경우 바로 NO를 출력해준다.

 

1. N을 20! 부터 0!까지 차례로 빼본다.

2. N >= arr[i]일 경우 N-=arr[i]을 한다.

3. 반복 후 N이 0일 경우 YES 아닐경우 NO를 출력한다.

 

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

백준 7568: 덩치[JAVA]  (0) 2024.04.12
백준 1018: 체스판 다시 칠하기[JAVA]  (0) 2024.04.11
백준 1476: 날짜 계산[JAVA]  (0) 2024.04.09
백준 1543: 문서 검색[JAVA]  (0) 2024.04.09
백준 1436: 영화감독 숌[JAVA]  (0) 2024.04.09

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

 

1476번: 날짜 계산

준규가 사는 나라는 우리가 사용하는 연도와 다른 방식을 이용한다. 준규가 사는 나라에서는 수 3개를 이용해서 연도를 나타낸다. 각각의 수는 지구, 태양, 그리고 달을 나타낸다. 지구를 나타

www.acmicpc.net

 

 

[난이도]

- Silver 5

 

[알고리즘]

- 부르트 포스

- 수학

 

[정답 코드]

import java.io.*;
import java.util.*;

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

        int E = Integer.parseInt(st.nextToken());
        int S = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        int e = 1, s = 1, m = 1;
        int answer = 1;

        while (true) {
            if (e == E && s == S && m == M) {
                break;
            }
            answer++;
            e++;
            if (e > 15) {
                e=1;
            }
            s++;
            if (s > 28) {
                s=1;
            }
            m++;
            if (m > 19) {
                m=1;
            }
        }
        System.out.println(answer);

    }
}

 

[풀이]

1. e = 1, s = 1, m = 1로 초기화 해준다.

2. e++, s++, m++을 하면서 e==E, s==S, m==M이 될때 까지 반복한다.

3. e는 15를 넘어갈 경우 1로 돌아온다. s는 28을 넘어갈 경우 1로 돌아온다. m은 19를 넘어갈 경우 1로 돌아온다.

4. answer를 반환한다.

 

좀더 수학적으로 스마트하게 풀 수 있는 방법이 있을것 같은데 내 머리로는 불가능 했다.

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

 

1543번: 문서 검색

세준이는 영어로만 이루어진 어떤 문서를 검색하는 함수를 만들려고 한다. 이 함수는 어떤 단어가 총 몇 번 등장하는지 세려고 한다. 그러나, 세준이의 함수는 중복되어 세는 것은 빼고 세야 한

www.acmicpc.net

 

[난이도]

- Silver 5

 

[알고리즘]

- 부르트 포스

- 문자열

 

[정답 코드]

import java.io.*;
import java.util.*;

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

        String words = br.readLine();
        String searchWord = br.readLine();
        int answer = 0;

        while (words.contains(searchWord)) {
            words = words.replaceFirst(searchWord, "_");
            answer++;
        }
        System.out.println(answer);

    }
}

 

[풀이]

1. 문서속에 검색하고 싶은 단어가 포함되면 while문 반복

2. 문서속에 검색하고 싶은 단어를 임의로 "_"로 변경 (String.replaceFirst() 메서드를 활용)

3. 변경했다면 answer 1증가

4. answer 출력

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

백준 2057: 팩토리얼 분해[JAVA]  (0) 2024.04.10
백준 1476: 날짜 계산[JAVA]  (0) 2024.04.09
백준 1436: 영화감독 숌[JAVA]  (0) 2024.04.09
백준 1251: 단어 나누기[JAVA]  (0) 2024.04.09
백준 4179: 불![JAVA]  (0) 2024.04.04

+ Recent posts