오늘은 기존에 배웠던 개념을 복습했던 날인 것 같다
3번 문제에서 많이 어려움을 느꼈다...
옆으로도 돌려보고 찢어도 보고 했는데, 결국 좌표로 구해서 풀었다.
클래스도 만들어 보긴 했으나 자꾸 실패가 떠서 어려웠다
=========================================================================
풀었던 문제
[백준 2108번 통계학]
https://www.acmicpc.net/problem/2108
package src.com.company.week2.day4;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
/**
* 메모리 : 64540KB, 시간 840ms
*
* */
public class BJ_2108_통계학 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] numArray = new int[N];
int sum = 0;
int midIndex = N / 2;
//최빈값 구하기 위한 맵
Map<Integer, Integer> map = new TreeMap<>();
for(int i = 0; i < N; i++) {
// 값 넣으면서
numArray[i] = Integer.parseInt(br.readLine());
// 산술평균에 필요한 합 구하고
sum += numArray[i];
// 최빈값 구하는 맵에도 넣고(키: 배열요소, 값: 빈도수)
map.put(numArray[i],map.getOrDefault(numArray[i],0) + 1);
}
// 오름차순 정렬
Arrays.sort(numArray);
//1. 산술평균 : 은근.. 자료형이 어려웠습니다.
int average = calculateAverage(sum, N);
System.out.println(average);
//2. 중앙값
int median = numArray[midIndex];
System.out.println(median);
//3. 최빈값
int frequency = calculateFrequency(map);
System.out.println(frequency);
//4. 범위
int range = Math.abs(numArray[N-1] - numArray[0]);
//int range2 = numArray[N-1] - numArray[0];
System.out.println(range);
}
public static int calculateAverage(int sum, int N) {
double doubleAverage = (double) sum / N;
if(doubleAverage < 0) {
// 여기서 애먹었다.. 음수 양수로 만들고(절댓값) 다시 음수 만들고 반올림(round) 해줘야 함
return (int) Math.round(Math.abs(doubleAverage) * -1);
} else {
return (int) Math.round(doubleAverage);
}
}
public static int calculateFrequency(Map<Integer, Integer> map) {
//(키: 배열요소, 값: 빈도수) 인 맵 : 빈도수 큰 것부터 정렬
int freq = Collections.max(map.values());
// 최빈값 배열
ArrayList<Integer> arrayList = new ArrayList<>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
//해당 value값이 maxValue값과 같으면 또 최빈값이 있는거니까 키값(원래의 값 넣어주기)
if (entry.getValue() == freq) {
arrayList.add(entry.getKey());
}
}
// 두번째 작은 값 구하기
if(arrayList.size() > 1) {
return arrayList.get(1);
}
else {
return arrayList.get(0);
}
}
}
여기서 문제가 같은 최빈값을 갖는 숫자가 있으면 두번째로 작은 수를 출력하라고 한다.
나는 일단 트리맵에 리버스 오더 해서 저장할 때 부터 키값(배열 요소) 들이 작은 값들을 구했고, maxValue 통해 (최빈값)을 구해놓고,
맵 안에 그 값과 같은 값이 있으면 arrayList 에 담아두었다.
그래서 리스트에 최빈값 하나면 그거 꺼내고, 하나 이상이면 두번째로 큰 것(인덱스 1번) 을 꺼내줬다
====================================================================
[백준 2304번 창고 다각형]
푼 사람들의 풀이가 모두 달랐다.
https://www.acmicpc.net/problem/2304
package src.com.company.week2.day4;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
/**
* 메모리 : 15312KB, 시간 : 144ms
* 입력값을 이차원 배열[인덱스][x좌표, y좌표]형식으로 받았다 : columns[index][2,4]
* 1. 정렬 :입력받은 배열을 그림처럼 나열하기 위해(x좌표 기준으로 탐색할꺼니까)
* 2. 현재 위치 :i (2,4 중 4)와 다음 위치: j(4,6 중 6) 의 높이 비교, 더 낮은거 나올 때 까지 반복 : columns[j][1]이런식으로..
* 즉, 사이사이 값 넓이 찾아서 더해주는 식으로 구현함
* */
public class BJ_2304_창고다각형_2 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
//이차원 배열로 풀었다. x, y좌표 기록용
int[][] columns = new int[N][2];
// 입력 : columns[index][2,4] 이렇게 저장되게 -> columns[0][2,4]
for (int i = 0; i < N; i++) {
String[] input = br.readLine().split(" ");
// x좌표
columns[i][0] = Integer.parseInt(input[0]);
// y 좌표
columns[i][1] = Integer.parseInt(input[1]);
}
//x 좌표를 기준으로 정렬하기(if (columns[i][0] > columns[i + 1][0]) : 바꿔치기
Arrays.sort(columns, Comparator.comparingInt(x -> x[0]));
// 그.. 네모 넓이 초기화
int area = 0;
// i 의 값이 안변하는 이유 : max로 잡아놓을 때만 바꿔야 네모를 그릴 수 있기 때문에
for (int i = 0; i < N;) {
int j = i + 1; // 현재 기둥 다음 기둥부터 시작
int maxIndex = j; // 최대 높이의 기둥 인덱스
// 현재 기둥보다 높이가 낮은 기둥이 나올 때까지 반복
// j가 1000(범위) 안넘을때, [0][2,4]와 [1][4,6] -> 즉 4와 6을 비교 / 6,3을 비교
while ((j < N) && (columns[i][1] > columns[j][1])) {
// 최대 높이 바꿔치기 : 최대 높이 아직 6
if (columns[maxIndex][1] < columns[j][1])
maxIndex = j;
j++;
}
// 마지막 기둥의 경우
if (j == N) {
// 현재 기둥의 높이만큼 면적 추가
area += columns[i][1];
// 큰게 또 나올 경우
if (maxIndex < N) {
area += columns[maxIndex][1] * (columns[maxIndex][0] - columns[i][0] - 1);
}
i = maxIndex;
} else { // 다음 기둥이 있는 경우
// 현재 기둥과 다음 기둥 사이의 너비 * 현재 기둥 높이로 면적 추가 2 * 4
area += columns[i][1] * (columns[j][0] - columns[i][0]);
i = j;
}
}
System.out.println(area);
}
}
나는 사각형을 여러개로 잘라 최고높이가 나올때 마다 갱신하고, 최고높이의 x좌표가 N(x좌표 맨 끝) 이 아니라면은 낮은거 찾는 식으로 구현했다.
개인적으로 나는 시간도 중요하지만, 가독성을 떠나 사람들이 이해하기 좋은 코드(쉬운코드)가 참 좋다고 생각하는데, 팀원들 중에 가로로 높이만큼 찢어서 푸는 코드가 있어서 좋은 아이디어라고 생각했다.
이번 조는 레벨이 더 높아지고 깊이있는 공부를 해서 그런지
풀이법 보다 시간과 공간에 대해 공부를 더 하는 느낌이다.
나는 코드를 한줄한줄 보는 느낌이고.. 다른 견해를 보는 것 같아 좋다!
+) 아직 내가 시간보다는 문제를 코드레벨로 구현하는 단계여서 그럴지도..?
'항해99 취업 리부트 코스 학습일지' 카테고리의 다른 글
[항해99 취업 리부트 코스 학습일지] 2024.04.09(화) (0) | 2024.04.09 |
---|---|
[항해99 취업 리부트 코스 학습일지] 2024.04.08(월) (0) | 2024.04.09 |
[항해99 취업 리부트 코스 학습일지] 2024.04.04(목) (0) | 2024.04.05 |
[항해99 취업 리부트 코스 학습일지] 2024.04.03(수) (0) | 2024.04.04 |
[항해99 취업 리부트 코스 학습일지] 2024.04.01.(월) (0) | 2024.04.01 |