250223 회고 💬

코로나에 걸렸다. 세 번째다. 괴롭다. 몸살에 콧물, 가래 등등 괴로운 1주였다. 아침에 일어나는데 너무 힘들어서 병원을 다녀오기까지 했다. 코로나에 혹사당한 2월 넷째 주를 되돌아본다.

Keep 👍

  • 알고리즘 문제 풀이를 계속하고 있다. 코테 스터디를 하고 있다. 혼자 공부할 때는 쉬운 브론즈 문제 풀면서 구색만 맞추곤 했다. 그런데 이제는 강제적으로 골드 문제를 풀게 되었다. 이번 주 기출 문제는 나무 재테크이다. 기본 문제 주제로는 백트래킹, 이분탐색이다. 백트래킹은 어느 정도 되는데 이분탐색이 문제다. 늘 새로운 내용,,, 어렵다 어려워! 브론즈만 풀었다고 하지만 그래도 1년 넘게 공부해서 그런지 1시간 내외로 골드 문제를 풀 수는 있다. 🤪
  • 스프링 부트 강의를 다 들었다! 다음으로 뭐 들을지 고심한 결과 자바 멀티스레딩을 공부하기로 했다. 거의 모르는 내용이라 한번은 정리하고 넘어가야 하기도 했고, 동시성 처리 문제가 종종 필요하기 때문에 시작했다.
    - springboot
    - 마이크로미터
    - multi thread
    - life cycle
    - 메모리 가시성
    - synchronized
    - 생산자 소비자 문제
  • 개인 프로젝트 진행할 시간 내기가 참 힘들다. 이번 주에 SSAFY에서 순열, 조합, 부분집합 관련 알고리즘 문제를 내줬는데 이것들 처리하다보니 개인프로젝트 진행을 하나도 못했다.
  • CS 스터디를 진행했다. 이번 주에는 메모리와 컴퓨터 주변 기기들을 학습했다.
    - 메모리, 캐시
    - 하드디스크
    - 드라이버

Try 🧚

  • SSAFY B형 대비 문제 풀이하기
  • 삼성 기출 문제집 문제 풀이
  • 토이 프로젝트 비디오 업로드 로직 완성
    - 백엔드
    - 개인 프로필 로직 제작
    - 비디오 업로드 로직
    - 프론트엔드
    - 개인 프로필 화면 제작
    - 비디오 화면 제작

독서 목록

서평 완료 목록

서평 예정 목록 (읽는 중)

  • 면접을 위한 CS 전공지식 노트

독서 예정 목록

  • 오브젝트
  • HTTP 완벽 가이드
  • 자바/스프링 개발자를 위한 실용주의 프로그래밍
  • 모던 자바 인 액션
  • 자바 성능 튜닝 이야기
  • 헤드 퍼스트 서블릿
  • 파이브 라인스 오브 코드

Extras 😀

나무 재테크

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.util.*;  
  
public class Main {  
  
    public static void main(String[] args) {  
       new Main().run();  
    }  
  
    private void run() {  
       try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {  
  
          Input ip = readInput(br);  
          Solution s = new Solution();  
          System.out.println(s.solution(ip.years, ip.fertilizeInfo, ip.treeInfo));  
  
       } catch (IOException e) {  
          throw new RuntimeException(e);  
       }  
    }  
  
    private Input readInput(BufferedReader br) throws IOException {  
       StringTokenizer st = new StringTokenizer(br.readLine());  
       int fertilizeLen = Integer.parseInt(st.nextToken());  
       int numOfTrees = Integer.parseInt(st.nextToken());  
       int years = Integer.parseInt(st.nextToken());  
  
       int[][] fertilizeInfo = new int[fertilizeLen][fertilizeLen];  
  
       for (int i = 0; i < fertilizeLen; i++) {  
          st = new StringTokenizer(br.readLine());  
          for (int j = 0; j < fertilizeLen; j++) {  
             fertilizeInfo[i][j] = Integer.parseInt(st.nextToken());  
          }  
       }  
  
       int[][] treeInfo = new int[numOfTrees][3];  
       for (int i = 0; i < numOfTrees; i++) {  
          st = new StringTokenizer(br.readLine());  
          treeInfo[i][0] = Integer.parseInt(st.nextToken()) - 1;  
          treeInfo[i][1] = Integer.parseInt(st.nextToken()) - 1;  
          treeInfo[i][2] = Integer.parseInt(st.nextToken());  
       }  
  
       return new Input(years, fertilizeInfo, treeInfo);  
    }  
  
    private static class Input {  
  
       final int years;  
       final int[][] fertilizeInfo;  
       final int[][] treeInfo;  
  
       public Input(int years, int[][] fertilizeInfo, int[][] treeInfo) {  
          this.years = years;  
          this.fertilizeInfo = fertilizeInfo;  
          this.treeInfo = treeInfo;  
       }  
    }  
}  
  
class Solution {  
  
    private Field field;  
    private PriorityQueue<Tree> trees;  
    private Queue<Tree> deadTrees;  
  
    public int solution(int years, int[][] fertilizeInfo, int[][] treeInfo) {  
       init(fertilizeInfo, treeInfo); // 풀이 로직 초기화  
  
       while (years-- > 0) { // 주어진 년도 반복  
          spring();  
          summer();  
          fall();  
          winter();  
       }  
       return trees.size(); // 끝나고 남은 나무의 개수 반환  
    }  
  
    private void init(int[][] fertilizeInfo, int[][] treeInfos) {  
       this.field = new Field(fertilizeInfo);  
       this.trees = new PriorityQueue<>();  
       this.deadTrees = new ArrayDeque<>();  
       for (int[] treeInfo : treeInfos) {  
          this.trees.offer(new Tree(treeInfo[0], treeInfo[1], treeInfo[2]));  
       }  
    }  
  
    private void spring() {  
       PriorityQueue<Tree> newTrees = new PriorityQueue<>();  
       // 자라난 나무들 임시 저장  
  
       while (!trees.isEmpty()) {  
          Tree tree = trees.poll();  
          if (field.afford(tree)) {  
             // 만약 나무가 먹을 양분이 있으면  
             field.sock(tree);  
             // 땅에서는 양분이 사라지고  
             tree.grow();  
             // 나무는 자라남  
             newTrees.offer(tree);  
             // 임시 저장  
          } else {  
             deadTrees.offer(tree);  
             // 먹을게 없으면 으앙 쥬금  
          }  
       }  
       trees = newTrees;  
       // 임시 나무들을 다시 원래 변수에 저장  
    }  
  
    private void summer() {  
       for (Tree deadTree : deadTrees) {  
          // 죽은 나무들을  
          field.fertilizeWith(deadTree);  
          // 땅의 비료로  
       }  
       deadTrees.clear();  
       // 이거 안 해서 시간초과 났음  
    }  
  
    private void fall() {  
       int[][] DIRECTIONS = {{0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}};  
       // 8방향 탐색  
  
       Queue<Tree> temp = new ArrayDeque<>();  
       // 새로 생긴 나무들 임시 저장  
  
       for (Tree tree : trees) {  
          if (tree.age % 5 != 0) continue;  
          // 나이가 5배수가 아니면 스킵  
  
          for (int[] direction : DIRECTIONS) {  
             int nx = tree.x + direction[0];  
             int ny = tree.y + direction[1];  
  
             if (field.isOutOfField(nx, ny)) continue;  
             // 밭 범위를 벗어나면 스킵  
  
             temp.offer(new Tree(nx, ny, 1));  
             // 새로운 나무 임시 저장  
          }  
       }  
       trees.addAll(temp);  
       // 새로 생긴 나무들 모두 저장  
    }  
  
    private void winter() {  
       field.fertilize();  
       // 주어진 수치만큼 땅에 비료 추가  
    }  
}  
  
class Tree implements Comparable<Tree> {  
  
    int x;  
    int y;  
    int age;  
  
    public Tree(int x, int y, int age) {  
       this.x = x;  
       this.y = y;  
       this.age = age;  
    }  
  
    public void grow() {  
       age++;  
    }  
  
    @Override  
    public int compareTo(Tree o) {  
       return Integer.compare(age, o.age);  
    }  
}  
  
class Field {  
  
    private int[][] field;  
    private int[][] fertilizeInfo;  
  
    public Field(int[][] fertilizeInfo) {  
       this.fertilizeInfo = fertilizeInfo;  
       this.field = new int[fertilizeInfo.length][fertilizeInfo.length];  
       for (int[] f : field) {  
          Arrays.fill(f, 5);  
          // 땅의 초기값은 5  
       }  
    }  
  
    public boolean afford(Tree tree) {  
       return field[tree.x][tree.y] >= tree.age;  
       // 나무가 먹을 만큼 영양분이 있는지?  
    }  
  
    public void sock(Tree tree) {  
       field[tree.x][tree.y] -= tree.age;  
       // 나무가 영양분 빨아감  
    }  
  
    public boolean isOutOfField(int x, int y) {  
       return x < 0 || x >= field.length || y < 0 || y >= field.length;  
    }  
  
    public void fertilize() {  
       // 지역에 정해진 양만큼 영양분 추가  
       for (int i = 0; i < field.length; i++) {  
          for (int j = 0; j < field.length; j++) {  
             field[i][j] += fertilizeInfo[i][j];  
          }  
       }  
    }  
  
    public void fertilizeWith(Tree tree) {  
       // 죽은 나무를 영양분으로 변환  
       field[tree.x][tree.y] += (tree.age / 2);  
    }  
}
profile
What doesn't kill you, makes you stronger

0개의 댓글

Powered by GraphCDN, the GraphQL CDN