Red Glitter Pointer

 

풀이 : 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에 저장해준다.

 

느낀점 및 정리 ✍️

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

 

 

 

 

5637번: 가장 긴 단어

단어는 알파벳(a-z, A-Z)과 하이픈(-)으로만 이루어져 있다. 단어와 다른 문자(마침표, 숫자, 심볼, 등등등...)로 이루어진 글이 주어졌을 때, 가장 긴 단어를 구하는 프로그램을 작성하시오. Apple의

www.acmicpc.net

 

 

 

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

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String answer = "";
        int max = Integer.MIN_VALUE;

        outer:
        while(true) {
            String[] arr = br.readLine().trim().split(" "); // 앞뒤 공백 제거 후 나눠서 배열에 저장
            for (int i = 0; i < arr.length; i++) {
                arr[i] = arr[i].replaceAll("[^a-zA-Z-]", " ").trim(); // 정규표현식 사용하여 a-z,A-Z,-는 모두 공백으로 변경 후 앞뒤 공백 제거
                String[] temp = arr[i].split(" "); // 변경된 문자열을 공백 기준으로 나눠서 저장

                for(int j = 0; j < temp.length; j++) {
                    if(temp[j].equals("E-N-D")) break outer; // E-N-D 일 경우 종료시키기
                    if (max < temp[j].length()) { // 최댓값 갱신 및 가장 긴 단어 저장
                        max = temp[j].length();
                        answer = temp[j];
                    }
                }
            }
        }
        System.out.println(answer.toLowerCase()); // 소문자로 출력
    }
}

 

 

느낀 점 및 정리✍️

1. 첫 제출에서 틀렸다고 나와서 문제 다시 읽어보니 "소문자로 출력" 이라는 조건이 있길래 toLowerCase()만 붙여서 제출했더니 또 틀렸다고 나왔다. 입력 예제가 1개 뿐이라 해당 예제로는 출력이 잘 되었어서 몰랐는데 문제를 다시 읽어보니 "단어는 알파벳(a-z, A-Z)과 하이픈(-)으로만 이루어져 있다" 라고 되어있는걸 발견했다. ㅎㅋ; ;; 기존 작성했던 코드에서 replaceAll("[^a-zA-Z-]") 정규표현식을 추가해서 a-z, A-Z, - 제외한 나머지는 공백으로 대체시켰다. 

2. 이번에 정규표현식을 쓰면서 ^[a-zA-z] 와 [^a-zA-z]의 차이점에 대해 알게되었다 ... !!!!!!!!! 별거 아니지만 뭔가 또 하나 배웠다는 생각에 기분이 좋았따 ㅎ "^[a-zA-Z]" translates to "begins with character from a-z or A-Z", and "[^a-zA-Z]" translates to "is not either a-z or A-Z"

3. 오늘의 느낀 점.... 문제 좀 꼼꼼하게 잘 읽고 중요한 조건같은건 미리 적어두자 !!! 

4. 예제 입출력만 테스트 해보고 끝내지 말고, 내가 직접 예외적인 사항들 포함해서 테스트케이스 만들어서 테스트 해보기! 

 

 

 

17413번: 단어 뒤집기 2

문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다. 먼저, 문자열 S는 아래와과 같은 규칙을 지킨다. 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져

www.acmicpc.net

 

 

 

 

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

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder total = new StringBuilder(); // 출력할 문자열
        StringBuilder now = new StringBuilder(); // 현재 문자열
        boolean flag = false; // <> 안에 들어있는 단어인지 판단하기 위한 변수
        char[] arr = br.readLine().toCharArray();

        for(int i = 0; i < arr.length; i++) {
            if(arr[i] == '<') {
                flag = true; // <가 시작되면 true로 변경
                total.append(now.reverse()); // '<' 전까지 입력되었던 문자열 뒤집어서 저장
                now = new StringBuilder(); // 현재 문자열 초기화
                now.append('<'); // 현재 문자열에 '<' 추가
            } else if(arr[i] == '>') {
                flag = false; // >로 닫히면 false로 변경
                now.append(arr[i]); // 현재 문자열에 '>' 추가
                total.append(now); // '>'까지 입력된 문자열 그대로 저장
                now = new StringBuilder(); // 현재 문자열 초기화
            } else if(arr[i] == ' ' || i == arr.length - 1) { // 공백이거나 맨 마지막 문자일 경우
                if(flag) { // <> 안에 있는 문자라면 현재 문자열에 그대로 추가
                    now.append(arr[i]);
                } else { // <> 안에 있는 문자가 아니라면 
                    if(i == arr.length - 1) { // 문자열의 맨 마지막 문자일 경우
                        now.append(arr[i]); // 현재 문자열에 추가
                        total.append(now.reverse()); // 뒤집어서 저장
                    } else { // 공백일 경우
                        total.append(now.reverse()).append(' '); // 뒤집은 다음 공백 저장
                    }
                    now = new StringBuilder();
                }
            } else {
                now.append(arr[i]); // 문자라면 현재 문자열에 그대로 저장
            }
        }
        System.out.println(total);
    }
}

 

느낀 점 및 정리✍️

1. 배열의 마지막 인덱스에 있을 경우와 공백의 경우는 디버깅하면서 추가 조건을 붙이게 되었다. 처음에는 그것까진 생각을 못했다 

2. 오늘 풀면서 String과 StringBuilder의 차이점이 궁금해졌다. 예를 들면 String answer = ""; answer += now; 로 하는 것과 sb.append(now) 하는 것의 차이가 궁금해져서 찾아보았는데 String은 문자열이 업데이트 될 때마다 계속해서 메모리 블럭 추가되고 일회용으로 사용된 이 메모리들은 Garbage Collector의 제거 대상이 되어 빈번하게 Minor GC를 일으킨다고 한다. 반면 StringBuilder는 자제 메모리 블럭에서 늘이고 줄이고 할 수 있기 때문에 훨씬 더 효율적으로 문자열 데이터를 다룰 수 있다고 한다! 정리하자면, 문자열 연산이 많을 경우 StringBuilder()가 낫다! 

 

 

 

설계 : 27분

풀이 : 12분

디버깅 : 6분

총 : 45분

 

 

1094번: 막대기

지민이는 길이가 64cm인 막대를 가지고 있다. 어느 날, 그는 길이가 Xcm인 막대가 가지고 싶어졌다. 지민이는 원래 가지고 있던 막대를 더 작은 막대로 자른다음에, 풀로 붙여서 길이가 Xcm인 막대

www.acmicpc.net

 

 

 

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

public class Main {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        int X = sc.nextInt();
        int stick = 64; // 현재 자르고 있는 막대기의 길이
        int count = 1; // 이어붙인 막대기 개수
        int sum = 0; // 이어붙인 막대기 길이

		// sum이 X와 일치하고, X가 stick의 길이와 같다면 실행하면 안됨
        while(sum != X && X != stick) {
            stick /= 2; // 막대기 자르기
            sum += stick; // 자른 막대기 이어붙여보기
            // 이어 붙인 막대기가 X보다 길다면 다시 떼어내기
            if(sum > X) {
                sum -= stick;
            // 이어 붙인 막대기가 X보다 짧다면 그대로 붙이고, 붙인 막대기 개수 증가 시키기
            } else if(sum < X) {
                count++;
            }
        }
        System.out.println(count);
    }
}

 

느낀점 및 정리 ✍️

1. 설계에서 생각보다 시간이 많이 걸렸다. 분명 쉽고 간단한 문제인게 보이는데 "절반 중 하나를 버린다" "가장 짧은 막대" 등 불필요한 조건에 집착해서 좀 헤매다보니 지체됐고, 다시 처음부터 생각해보자는 마음으로 새로 설계했더니 금방 해결책이 나왔다.

2. while문의 무한루프에 빠지는 것을 잘 .... 컨트롤 하자..

3. 불필요한 조건에 집착하지 말자 ㅠ ㅠ ~~~~~~ 

 

 

 

 

1924번: 2007년

첫째 줄에 빈 칸을 사이에 두고 x(1 ≤ x ≤ 12)와 y(1 ≤ y ≤ 31)이 주어진다. 참고로 2007년에는 1, 3, 5, 7, 8, 10, 12월은 31일까지, 4, 6, 9, 11월은 30일까지, 2월은 28일까지 있다.

www.acmicpc.net

 

 

 

 

 

 

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

public class Main {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        int y = sc.nextInt();

        int[] month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        String[] days = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};

        for(int i = 0; i < x - 1; i++) {
            y += month[i];
        }
        System.out.println(days[y % 7]);
    }
}

 

느낀점 및 정리 ✍️

1. 인덱스는 0부터 시작이지만 월은 1부터 시작이라 x - 1 해줬음

2. 1일이 월요일이라면 0이 일요일이기 때문에 인덱스를 7로 나눈 나머지 숫자로 활용하여 도출해낼 수 있다~~ 

 

 

 

 

1748번: 수 이어 쓰기 1

첫째 줄에 N(1 ≤ N ≤ 100,000,000)이 주어진다.

www.acmicpc.net

 

 

 

문제 보자마자 시간 제한은 안읽어보고 바로 푸느라고 메모리 초과가 떴다... ㅎ

메모리 초과 보고나서 제한 시간을 보니 이렇게 풀어서 맞았다면 브론즈 문제였겠지 싶긴 했다 ;

 

 

일단 정답 코드 👇

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

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 count = 0; // 총 자릿 수
        int upgrade = 1; // 현재 숫자의 자릿 수
        int num = 10; // 현재 숫자가 몇자리 숫자인지 확인하기 위한 변수

        for(int i = 1; i <= N; i++) {
            if(i % num == 0) {
                upgrade++; // 현재 숫자의 자릿 수를 1 늘려준다.
                num *= 10; // 10 -> 100 -> 1000 ...
            }
            count += upgrade; // 현재 자릿 수를 더해준다
        }

        System.out.println(count);
    }
}

 

1 ~ 9 까지는 1자리

10 ~ 99 까지 2자리

100 ~ 999 까지 3자리 ....

변경되는 기준점이 10, 100, 1000 ... 의 패턴이 있는 것을 볼 수 있다.

그래서 해당 기준점을 num이라는 변수를 선언해서, 나머지가 0일 경우 그 다음 기준점으로 변경(num *= 10) 해주고 자릿 수도 1씩 증가시켜주었다.

 

느낀 점 및 정리 ✍️

1. 문제를 꼼꼼하게 읽자 (시간 제한 등..)

 

 

 

알고리즘 문제 엄청 오랜만에 풀어서 브론즈 + 구현 문제로 시작해보았다.!!!

 

설계 시간 : 8분

풀이 시간 : 10분

디버깅 시간 : 6분

 

 

2979번: 트럭 주차

첫째 줄에 문제에서 설명한 주차 요금 A, B, C가 주어진다. (1 ≤ C ≤ B ≤ A ≤ 100) 다음 세 개 줄에는 두 정수가 주어진다. 이 정수는 상근이가 가지고 있는 트럭이 주차장에 도착한 시간과 주차장

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

        int[] price = new int[3]; // 주차요금 저장할 배열

        for(int i = 0; i < 3; i++) {
            price[i] = Integer.parseInt(st.nextToken());
        }

        int[] time = new int[101]; // 주어지는 시간 1~100
        int max = Integer.MIN_VALUE;

        int from = 0; // 주차장 도착 시간
        int to = 0; // 주차장 떠난 시간

        for(int i = 0; i < 3; i++) {
            st = new StringTokenizer(br.readLine());
            from = Integer.parseInt(st.nextToken());
            to = Integer.parseInt(st.nextToken());
            max = Math.max(Math.max(max, from), to); // 떠난 시간 최댓값 구하기
            for(int j = from; j < to; j++) {
                time[j]++;
            }
        }

        int result = 0;

        // 1부터 떠난 시간까지 시간마다 몇대의 차량이 주차되어있었는지 확인
        for(int i = 1; i <= max; i++) {
            if(time[i] > 0) {
                switch(time[i]) {
                    case 1:
                        result += price[0];
                        break;

                    case 2:
                        result += 2 * price[1];
                        break;

                    case 3:
                        result += 3 * price[2];
                        break;
                }
            }
        }
        System.out.println(result);
    }
}

 

느낀 점 및 정리 ✍️

 

1. 처음에 for(int j = from; j < to; j++) 이 부분에서 for(int j = from; j <= to; j++) 라고 적어서 조금씩 더 높은 숫자로 출력이 되었는데, 생각해보니 떠난 시간은 고려하면 안됐었다. 그래서 = 를 빼주었더니 원하는 결과값이 나옴!

2. result값 구할 때 max까지 돌게하지 않고 101까지 돌게 해도 되는데,,, 조금이나마,, 덜 돌게 하기 위해... 101이라 큰 차이는 없겠지만 ㅎ

3. 다음에 풀 때는 주차 요금을 배열로 생성해서 받지 않고 int 값으로 그냥 각각 받아서 사용할 것 같다. 굳이 for문 돌릴 필요가....

 

 

+ Recent posts

loading