문제

무인도에 갇힌 사람들을 구명보트를 이용하여 구출하려고 합니다. 구명보트는 작아서 한 번에 최대 2명씩 밖에 탈 수 없고, 무게 제한도 있습니다.

예를 들어, 사람들의 몸무게가 [70kg, 50kg, 80kg, 50kg]이고 구명보트의 무게 제한이 100kg이라면 2번째 사람과 4번째 사람은 같이 탈 수 있지만 1번째 사람과 3번째 사람의 무게의 합은 150kg이므로 구명보트의 무게 제한을 초과하여 같이 탈 수 없습니다.

구명보트를 최대한 적게 사용하여 모든 사람을 구출하려고 합니다.

사람들의 몸무게를 담은 배열 people과 구명보트의 무게 제한 limit가 매개변수로 주어질 때, 모든 사람을 구출하기 위해 필요한 구명보트 개수의 최솟값을 return 하도록 solution 함수를 작성해주세요.

 

제한 사항

  • 무인도에 갇힌 사람은 1명 이상 50,000명 이하입니다.
  • 각 사람의 몸무게는 40kg 이상 240kg 이하입니다.
  • 구명보트의 무게 제한은 40kg 이상 240kg 이하입니다.
  • 구명보트의 무게 제한은 항상 사람들의 몸무게 중 최댓값보다 크게 주어지므로 사람들을 구출할 수 없는 경우는 없습니다.

나의 코드

import java.util.*;
class Solution {
    public int solution(int[] people, int limit) {
        int answer = 0;
        Arrays.sort(people);
        int maxIndex = people.length - 1;
        for(int minIndex = 0; minIndex <= maxIndex; minIndex++) {
        	if(people[minIndex] + people[maxIndex] > limit) {
        		answer++;
        		maxIndex--;
        		minIndex--;
        	}
        	else if(people[minIndex] + people[maxIndex] <= limit) {
        		answer++;
        		maxIndex--;
        	}
        }
        return answer;
    }
}

나의 풀이

우선 보트가 작기 때문에 최대 두 명밖에 못 태운다는 것을 알아야 한다.

그러면 제일 큰사람, 제일 작은 사람을 같이 태워 보내야 한다는 결론이 난다.

1. people Array를 우선 정렬시켜준다.

2. maxIndex는 people Array의 길이 -1 로 설정해준다.

3. for문을 통해 minIndex를 0으로 설정해준다.

4. 만약 people[minIndex] + people[maxIndex]의 크기가 limit보다 크다면 

5. 제일 큰 사람만 배를 태워 보낸다. (maxIndex--, minIndex--, answer++)

6. 그게 아니라 people[minIndex] + people[maxIndex]의 크기가 limit보다 작거나 같으면

7. 제일 큰 사람, 제일 작은 사람 둘 다 태워서 보낸다. (maxIndex--, answer++)

8. answer return

문제

어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 합니다.

예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있습니다. 이 중 가장 큰 숫자는 94 입니다.

문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어집니다. number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하세요.

제한 조건

  • number는 1자리 이상, 1,000,000자리 이하인 숫자입니다.
  • k는 1 이상 number의 자릿수 미만인 자연수입니다.

나의 코드

class Solution {
    public static String solution(String number, int k) {
        String[] arr1 = number.split("");
        int[] arr = new int[arr1.length]; 
        for(int i=0; i<arr.length; i++) { arr[i] = Integer.parseInt(arr1[i]); }
        int cnt = arr.length-k;
        int left = 0;
        int right = k+1;
        StringBuilder sb = new StringBuilder();
        while(cnt>0) {
        	int max = 0;
        	for(int i=left; i<right; i++) {
        		if(arr[i]>max) {
        			max = arr[i];
        			left=i+1;
        		}
        	}
        	sb.append(max);
        	right++; cnt--;
        }
        return sb.toString();
    }
}

나의 풀이

탐욕법 알고리즘의 이름에 걸맞게 그 순간순간의 최댓값을 구해서 수를 완성시키면 된다.

테스트 케이스 10번에서 계속 시간 초과가 떠서 진짜 너무 답답했지만 number를 parsing 한 값들을 String으로 들고 int와

비교해줄 때마다 Integer.parseInt()를 사용해서 그런 것이었다. 그래서 그냥 처음부터 int[] array에 Integer.parseInt로 int로 가지고 있는다.

1. 우선 문자열 number를 parsing 하여 arr1 array에 저장한다.

2. int[] array를 선언하고 크기는 arr1.length로 해준다.

3. for문을 통해 String Array에 들어있는 값들을 int Array에 옮겨준다 ( Integer.parseInt를 통해 )

4. int cnt는 while문을 제어할 카운터 변수이다. 

5. int left 와 right는 Array의 왼쪽 index와 index가 오른쪽으로 몇 번 움직일지(right)를 판단해줄 변수이다.

6. int right의 초기값은 인자로 넘어온 k에 +1 해준 값으로 설정해준다. (arr [left]에서 right-left번 반복한다가 된다)

6. StringBuilder는 while문이 한번 돌 때마다 나오는 값을 append시켜주는데 그냥 String을 쓰는 것보다 효율적이라고 해서 사용

7. while문이 시작되면 int max를 초기화시켜준다. (max는 매 순간순간의 최댓값이 저장된다)

8. for문을 통해 left부터 right까지의 값 중에 최댓값을 if문을 통해 찾아낸다. 

9. 최댓값의 index를 찾았다면 그다음부터 탐색해야 하기 때문에 left=i+1이 된다.

10. for문이 끝나고 max가 도출되면 StringBuilder sb에 append 시켜준다.

11. right는 한 칸 늘려주고 cnt는 한번 빼준다.

12. return type이 String이기 때문에 return sb.toString()으로 마무리한다.

문제

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.

전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 전체 학생의 수는 2명 이상 30명 이하입니다.
  • 체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
  • 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
  • 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.
  • 여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.

나의 코드

class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        int answer = n-lost.length;
        
        for(int i=0; i<reserve.length; i++) {
        	for(int j=0; j<lost.length; j++) {
        		if(reserve[i]==lost[j]) {
        			reserve[i]=-1;
        			lost[j]=-1;
        			answer++;
        			break;
        		}
        	}
        }
        
        for(int i=0; i<lost.length; i++) {
            for(int j=0; j<reserve.length; j++) {
                if(lost[i]==reserve[j]+1 || lost[i]==reserve[j]-1) {
                    answer++;
                    reserve[j] = -1;
                    break;
                }
            }
        }
        return answer;
    }
}

나의 풀이

탐욕 법이라는 이름의 알고리즘을 처음 접했을 때 뭔가 대단한 건 줄 알았는데

사실 그냥 순간순간의 결정으로 돌아가는 알고리즘이었다.

지역(local)적으로는 최적화된 알고리즘일 수 있지만, 전역(global)의 시점으로 보면 최적화를 보장할 수 없다는 특징이 있다.

1. answer의 값을 n(총 인원수) - lost(도둑맞은 인원수)로 설정해준다.

3. 먼저 여벌을 가져왔지만 도둑맞아서 여벌을 자신이 입어야하는 사람을 구한다 (조건에 적혀있음)

2. 2중 for문을 통해 여벌을 가져왔지만 도둑을 맞은 인원을 -1로 설정해주어 다른 사람에게 못 빌려주도록 한다.

3. 또 다시 2중 for문을 통해 여벌을 가져온 사람의 사이즈에 +1이거나 -1인 lost들에게 빌려준다.

4. 빌려주고 나면 다시 못 빌려주게 빌려준 사람의 값을 -1로 바꾼다.

5. answer return

2020-06-14 09:00 ~ 14:50 독학사 1단계 시험 끝~~~~

 

아직 결과가 나온 건 아니지만

참.... 마음고생 많이 한 것 같다.

워낙 인문과목이랑은 담을 쌓아온지 오래됐던 터라 상당히 공부하는데 애를 많이 먹었다.

 

독학사에 대해서 여러 글을 찾아봤는데

1단계는 쉽다~ 쉽다~ 해주는 사람이 많아서 나도 모르게 안심이 됐었는지

거의 5일 벼락치기를 하게 되었다.

 

내년 독학사를 응시할 예정이라면 충분한 공부시간을 두라고 말해주고 싶다.

근데 확실한 건 영어 같은 경우는 기출문제보다 쉽게 나올 가능성이 아주 크다는 것!

기출문제를 풀 때 난이도가 너무 높은 것 같아서 괴로웠는데 생각보다 괜찮아서 아주 좋았다.

 

결과가 나와서 합격을 하여 합격후기를 올릴 예정인데 합격을 못하면 안 올릴 거다 ㅋㅋ

모자란 학점을 채우기 위한 시험이어서 4과목만 합격하면 장땡이라 4과목을 합격한다면 올리겠다.

 

덕수고등학교에서 응시했으며, 학교가 제법 커서 산책하기 좋았다.

마음이 예쁜 동생과 같이 가서 심심하지 않았다.

혼자 간다면 고독을 즐겨도 좋은 벤치들이 많이 준비되었으니, 만약 덕수고등학교가 걸리면 이어폰 챙기는 걸 권장한다.

 

덕수의 앞모습

 

덕수의 뒷모습

이제 내가 본 과목을 소개하겠다.

1교시 - 국어, 국사

국어와 국사를 동시에 응시하게 된다.

시험시간은 총 100분을 주며 한 시험지 뭉치에 같이 들어있다.

시간 분배는 그렇게 큰 신경 안 써도 될 만큼 충분하다. 그러니까 문제가 안풀린다고 조급해하지 말고 천천히 풀어보기를 권장한다.

국어의 기출 유형은 한글의 이해(20%), 현대, 고전소설-작품 위주(40%), 그 외(20%) 정도였던 것 같다.

지금 내 머릿속에 있는 정보니까 너무 신뢰는 안 했으면 좋겠다. 이것도 기출문제보다는 쉬웠다는 느낌을 받았다.

국사는 사실 공부를 안 했다. 패스 ㅋㅋ

 

2교시 - 영어

영어는 총 50분의 시험시간이 주어지며 시험 시작 30분이 지나면 점심 먹으러 떠나도 된다.

이것 또한 시간의 영향을 크게 받지 않으니 독해 문제 같은 경우는 처음부터 끝까지 읽어보는 걸 권장한다.

유의어 문제, 들어가기에 적합한 단어 고르는 문제가 10문제 이상 출제된..? 거 같다.

근데 중학교, 고등학교 때 영어를 힐끗힐끗 봤다면 놓치지 않을 문제들이었다.

그리고 독해 글이 10문제 이상 출제된..? 거 같은데 읽는데 큰 무리는 없을 것이다.

그 외 문법 문제는 좀 공부를 해야 할 것 같다.

영어, 너무 걱정하지 말자

 

점심

한양대가 앞에 있어서 그런지 먹을곳은 많다.

원래 동생이 찾아놓은 수제햄버거를 먹고싶었는데

교회를 나가셨는지 영업을 안했다. 그래서 선택한 맥도날드!

사람이 엄청 많은데 자동화가 잘 안되어있어 좀 불편함이 있었다!

3교시 - 현대사회와 윤리, 사회학개론

시험시간 100분을 준다. 시험방식은 국어,국사와 같다.

30분이 지난다면 퇴실이 가능하며, 집에 가도 좋다.

뭔가 생뚱맞은 과목이었지만 검색 결과 가장 흔히들 선택하고, 가장 쉽다는 의견이 많았기에 신청했던 과목이었다.

옛날 철학자들의 철학 문제들이 많이 출제된다.

이건 선택과목이라 다들 어떤 과목을 했는지 모르겠다.

사실 이 두 과목의 키포인트를 정리해주고 싶은데 성격이 너무 비슷한 과목이어서 머릿속에서 섞였다.

이건 처음 접하는 나로서는 키워드를 체크해가며 정리했다.

근데 생각보다 사회학개론의 문제가 좀 어려웠다.. 

내가 공부를 안 한 탓이겠지..

 

총 후기

독학사 1단계를 준비하고 있다면 너무 걱정하지 말고 넉넉한 기간을 잡아 넉넉하게 공부하면

좋은 점수를 받을 수 있을 것이라 확신한다. (키워드 위주로 공부!!!!)

사실 자신의 집중력이 정말 뛰어나다면 일주일 벼락치기를 해도 무관하다고 생각된다.

나는 집중력도 부족했고 시간도 없어서 사실 좀 불안하다.

그럼 독학사 합격 후기로 돌아올 수 있기를 바라며......

화이팅!

 

 

문제

Leo는 카펫을 사러 갔다가 아래 그림과 같이 중앙에는 노란색으로 칠해져 있고 테두리 1줄은 갈색으로 칠해져 있는 격자 모양 카펫을 봤습니다.

Leo는 집으로 돌아와서 아까 본 카펫의 노란색과 갈색으로 색칠된 격자의 개수는 기억했지만, 전체 카펫의 크기는 기억하지 못했습니다.

Leo가 본 카펫에서 갈색 격자의 수 brown, 노란색 격자의 수 yellow가 매개변수로 주어질 때 카펫의 가로, 세로 크기를 순서대로 배열에 담아 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 갈색 격자의 수 brown은 8 이상 5,000 이하인 자연수입니다.
  • 노란색 격자의 수 yellow는 1 이상 2,000,000 이하인 자연수입니다.
  • 카펫의 가로 길이는 세로 길이와 같거나, 세로 길이보다 깁니다.

나의 코드

public class Carpet {

	public static int[] solution(int brown, int yellow) {
        int[] answer = new int[2];
        int sum = brown+yellow;
        int h = (int)Math.pow(sum, 0.5);
//        int h = (int)Math.sqrt(sum);
        for(int i=3; i<=h; i++) {
        	if(sum%i==0) {
        		int t = sum/i;
        		if((t-2)*(i-2)==yellow) {
        			answer[0] = t;
        			answer[1] = i;
        		}
        	}
        }
        return answer;
    }

}

나의 풀이

풀이하기 나름이겠지만 완전 탐색 카테고리의 마지막 문제 치고 생각보다 간단한 문제였다.

1. 우선 answer의 크기는 무조건 2이기 때문에 2로 선언한다.

2. sum은 인자로 받은 brown과 yellow의 합을 저장한다.

3. int h 는 카펫의 세로 길이의 최댓값을 저장하고 있다.

제곱근을 구하는 방식이 두 개가 있는데 Math.sqrt를 사용하는 것과 Math.pow(숫자, 0.5)를 해주는 방법이 있다.

둘의 차이가 무엇인지 궁금해서 참고 자료를 가져왔다.

글에 나와있듯이 sqrt를 사용하는 것이 효율성 측면에서 더 좋은 것 같았다.

다음부터 sqrt를 사용해봐야겠다.

4. for문을 통해 높이의 최댓값 h까지 i를 증가시킨다 (i는 3 밑으로 떨어질 수가 없는 값이기 때문에 3부터 시작)

5. 만약 i(세로 길이)로 sum을 나누었을 때 0이 나머지가 0이 나오면

6. int t (가로길이) = sum을 i로 나눈 값의 몫이 된다.

7. 만약 (i-2) * (t-2) 의 값이 yellow와 같다면! (윗면에서 2칸을 빼고, 옆면에서 2칸을 빼서 곱한 값은 노란색의 개수가 된다)

8. answer[0] (가로길이) = t가 되며, answer[1] (세로 길이) = i 가 된다.

9. answer return

 

문제

숫자 야구 게임이란 2명이 서로가 생각한 숫자를 맞추는 게임입니다. 

게임해보기

각자 서로 다른 1~9까지 3자리 임의의 숫자를 정한 뒤 서로에게 3자리의 숫자를 불러서 결과를 확인합니다. 그리고 그 결과를 토대로 상대가 정한 숫자를 예상한 뒤 맞힙니다.

* 숫자는 맞지만, 위치가 틀렸을 때는 볼 * 숫자와 위치가 모두 맞을 때는 스트라이크 * 숫자와 위치가 모두 틀렸을 때는 아웃

예를 들어, 아래의 경우가 있으면

A : 123 B : 1스트라이크 1볼. A : 356 B : 1스트라이크 0볼. A : 327 B : 2스트라이크 0볼. A : 489 B : 0스트라이크 1볼.

이때 가능한 답은 324와 328 두 가지입니다.

질문한 세 자리의 수, 스트라이크의 수, 볼의 수를 담은 2차원 배열 baseball이 매개변수로 주어질 때, 가능한 답의 개수를 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 질문의 수는 1 이상 100 이하의 자연수입니다.
  • baseball의 각 행은 [세 자리의 수, 스트라이크의 수, 볼의 수] 를 담고 있습니다.

나의 코드

class Solution {
    public int solution(int[][] baseball) {
        int answer = 0;
        for(int i=1; i<=9; i++) {
        	for(int j=1; j<=9; j++) {
        		for(int k=1; k<=9; k++) {
        			if(i==j || j==k || i==k) continue;
        			int comp = 0;
        			for(int[] base : baseball) {
        				int one = base[0]/100;
        				int two = base[0]%100/10;
        				int three = base[0]%10;
        				int strike = 0;
        				int ball = 0;
        				if(one==i) strike++;
        				if(two==i || three==i) ball++;
        				if(two==j) strike++;
        				if(one==j || three==j) ball++;
        				if(three==k) strike++;
        				if(one==k || two==k) ball++;
        				
        				if(base[1]==strike && base[2]==ball) comp++;
        			}
        			if(comp==baseball.length) answer++;
        		}
        	}
        }
        return answer;
    }
}

나의 풀이

문제를 잘 해석해야 할 것이다. 진짜 코드 몇 글자 때문에 몇 시간을 날렸는지 모르겠다.

문제의 핵심은 0의 값이 안 들어간다는 것과 중복되는 숫자가 없어야 된다는 것.

1. 3중 for문을 이용하여 111에서 999까지 돌린다.

2. if문을 통해 중복되는 숫자를 체크해서 있다면 continue 해서 다음 숫자로 넘어간다.

3. comp는 마지막에 baseball 2차원 배열의 길이와 비교해줄 변수이다.

4. for문을 이용해 baseball에 담겨있는 추리들을 하나씩 가져온다.

5. int one, two, thee는 각각 첫째 자리와 둘째 자리, 셋째 자리를 저장할 변수이다.

6. strike와 ball은 이름에 나와있듯이 스트라이크 횟수와 볼의 횟수를 저장할 변수이다.

7. 순서대로 만약 one과 i가 같다면 strike 그 외에 같은 게 있다면 ball, k까지 비교해준다.

8. 그러면 baseball의 strike(1) 와 ball(2) 을 비교해서 모두 맞다면 comp++ 해준다.

9. 마지막으로 comp의 크기와 baseball의 length를 비교한다. 이게 맞다는 건 모든 경우의 수를 통과했다는 것.

10. answer를 return 해준다.

 

+ Recent posts