Day23

강태훈·2026년 1월 29일

nbcamp TIL

목록 보기
23/58

자료구조 및 알고리즘

ch2 추가문제

문제

실험실 산성 반응 테스트

실험실에서 산성 용액의 전파 효과를 테스트합니다. 실험대에 놓인 비커들은 산성 용액이 떨어졌을 때 특정한 패턴으로 반응하며, 각 비커에 담긴 물의 양이 다릅니다. 이번 실험에서 어떤 비커를 선택했을 때 가장 많은 양의 물이 산성으로 변하는지 알아보려 합니다.

산성 용액의 전파 패턴

산성 용액이 떨어진 비커를 중심으로 상하좌우로 전파됩니다
* 중심 비커와 상하좌우 4개의 비커가 영향을 받습니다
* 예시: 아래 배치에서 19에 떨어뜨리면 19,14,18,24,20가 산성으로 변합니다

제한사항

  • 실험대의 크기는 4 x 4 이상 120 x 120 이하입니다.
  • 각 비커에 담긴 물의 양은 1 이상 100 이하의 자연수입니다.
  • 전파는 실험대 범위를 벗어나지 않습니다.

입력 형식

  • T: 테스트케이스 수
  • P, Q: 각 테스트케이스의 실험대 크기
  • W: P x Q 크기의 2차원 배열로, 각 비커에 담긴 물의 양
2
4 4
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
5 5
2 4 6 8 10
12 14 16 18 20
22 24 26 28 30
32 34 36 38 40
42 44 46 48 50

출력 형식

  • String 타입의 문자열
    • 각 테스트케이스마다 "#T 최대값" 형식으로 출력
    • T는 테스트케이스 번호, 최대값은 산성으로 변하는 물의 총량
#1 56
#2 190

예시 상황 설명
다음과 같은 실험대가 주어졌을 때, 최적의 위치를 찾아 최대값을 반환하면 됩니다:

  1. 4x4 실험대의 경우:

    1  2  3  4
    5  6  7  8
    9 10 11 12
    13 14 15 16
    

    중앙의 6에 떨어뜨린 경우:

    • 영향 받는 비커: 2 + 5 + 6 + 7 + 10 = 30
    • 다른 모든 위치를 계산해본 결과 15에서 떨어뜨린 경우 56이 최대값
  2. 5x5 실험대의 경우:

    2  4  6  8 10
    12 14 16 18 20
    22 24 26 28 30
    32 34 36 38 40
    42 44 46 48 50
    

    26을 중심으로 선택한 경우:

    • 영향 받는 비커: 16 + 24 + 26 + 28 + 36 = 130
    • 다른 모든 위치를 계산해본 결과 38에서 떨어뜨린 경우 190이 최대

내 코드


main


public class Faintest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int count;
        int length;
        int width;

        System.out.println("세로와 가로 길이를 입력하세요: ");
        length = scanner.nextInt();
        width = scanner.nextInt();

        Beaker.amount(length,width);
    }
}

beaker


public class Beaker {
    public static void amount(int length, int width){
        Scanner sc = new Scanner(System.in);

        System.out.println(length + "X" + width + " 크기의 실험대");
        int[][] beakers = new int[length][width];
        for(int i = 0; i < length; i++){
            for(int j = 0; j < width; j++) {
                 beakers[i][j] = sc.nextInt();
            }
        }

        int[][] amounts = new int[length][width];

        final int[] dx = {0, 0, 0, -1, 1};
        final int[] dy = {0, -1, 1, 0, 0};

        for (int i = 0; i < length; i++) {
            for (int j = 0; j < width; j++) {
                int sum = 0;

                for (int d = 0; d < 5; d++) {
                    int ni = i + dx[d];
                    int nj = j + dy[d];

                    if (ni >= 0 && ni < length && nj >= 0 && nj < width) {
                        sum += beakers[ni][nj];
                    }
                }

                amounts[i][j] = sum;
            }
        }

        int maximum = Integer.MIN_VALUE;
        int maxi = Integer.MIN_VALUE;
        int maxj = Integer.MIN_VALUE;
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < width; j++) {
                if (maximum<amounts[i][j]) {
                    maximum = amounts[i][j];
                    maxi = i;
                    maxj = j;
                }
            }
        }
        System.out.println("최댓값: " + maximum);
        System.out.println("좌표: [" + maxi+1 + "," + maxj+1 + "]");

        sc.close();
    }
}

        for(int i = 0; i < length; i++){
            for(int j = 0; j < width; j++) {
                if(j == 0){
                    if(i == 0){
                        amounts[i][j] = beakers[i][j] + beakers[i][j+1] + beakers[i+1][j];
                    }
                    else if(i == length-1){
                        amounts[i][j] = beakers[i-1][j] + beakers[i][j] + beakers[i][j+1];
                    }
                    else{
                        amounts[i][j] = beakers[i-1][j] + beakers[i][j] + beakers[i][j+1] + beakers[i+1][j];
                    }
                }
                else if(j == width-1) {
                    if(i == 0){
                        amounts[i][j] = beakers[i][j-1] + beakers[i][j] + beakers[i+1][j];
                    }
                    else if(i==length-1){
                        amounts[i][j] = beakers[i-1][j] + beakers[i][j-1] + beakers[i][j];
                    }
                    else{
                        amounts[i][j] = beakers[i-1][j] + beakers[i][j-1] + beakers[i][j] + beakers[i+1][j];
                    }
                }
                else {
                    if(i == 0){
                        amounts[i][j] = beakers[i][j-1] +beakers[i][j] + beakers[i][j+1] + beakers[i+1][j];
                    }
                    else if(i == length-1){
                        amounts[i][j] = beakers[i-1][j] + beakers[i][j-1] + beakers[i][j] + beakers[i][j+1];
                    }
                    else{
                        amounts[i][j] = beakers[i-1][j] + beakers[i][j-1] + beakers[i][j] + beakers[i][j+1] + beakers[i+1][j];
                    }
                }
            }
        }

기존에 사용한 코드. 가독성이 떨어져서 변경



기초 Spring

챕터1: Spring 시작하기

  • JSON
    • 클라이언트와 서버가 통신할 때 사용하는 데이터 양식
    • 클라이언트와 서버가 사용하는 언어에 관계 없이 통일된 데이터를 주고받을 수 있도록 만들어준다
    • KeyValue로 이루어진 데이터를 정리하는 방식
    • Value는 또 다른 Key/Value가 될 수 있다
  • XML
    • 같은 데이터라도 XML은 JSON보다 가독성이 떨어지고 용량 면에서도 비효율적이므로 요즘은 거의 사용하지 않음
  • 라이브러리
    • 애플리케이션 개발에 필요한 클래스, 함수 등을 모아 놓은 코드의 모음
    • 개발자가 소프트웨어를 만들 때 필요에 따라 원하는 기능을 구현하기 위해 가져다 쓸 수 있는 일종의 도구 역할을 수행
  • 프레임워크
    • 소프트웨어 개발을 간편하게 만들기 위한 소프트웨어 개발 환경
    • 일하기 위한 틀을 제공하고 개발자는 해당 틀 안에서 개발해야함
    • 프레임워크는 라이브러리들의 모음
  • 스프링 프레임워크
    • 자바(Java) 플랫폼을 위한 오픈 소스 애플리케이션 프레임워크.
    • 간단히 스프링(Spring)이라고 부름
  • HTTP
    • 웹에서 데이터를 주고받기 위한 통신 규약
    • 편지를 주고받는 것과 비슷하게, 보내는 사람, 받는 사람, 내용이 정해진 형식으로 전달
    • 특징:
      • 무상태 (Stateless): 서버는 클라이언트의 상태(State)를 보존하지 않는다.
  • API
    • 프로그램끼리 대화하는 방법
    • 어떤 요청을 할 수 있고 어떤 응답을 받을 수 있는지 정의
    • API는 인터페이스
    • RESTful API
      • 어떻게 서버 구현을 알지 못하는 클라이언트가 API를 잘 이용할 수 있을지에 대한 고민의 결과
      • RESTful API 디자인 원칙
        1. 동사보단 명사를, 단수보단 복수를
        2. 마지막에 /넣지않기
        3. _대신 -사용 +대문자 사용하지않기
        4. 확장자 포함하지 않기(png, exe등)
        5. 계층화 하기
  • Annotation
    • 자바 코드에 메타 데이터를 추가하여 코드에 특별한 의미를 부여하거나, 컴파일러와 런타임에 특정 동작을 트리거하기 위해 사용
    • 예: @Override
  • Lombok 라이브러리
    • 보일러 플레이트 코드를 줄여주는 라이브러리
    • 자동으로 보일러 플레이트 코드를 생성하여 코드의 가독성과 유지보수성을 높여줌
    • Annotation기반으로 동작하며, 주로 컴파일 시점에 소스 코드를 변환하여 필요한 메서드를 자동으로 생성

보일러 플레이트 코드(Boilerplate code)란?
-> getter/setter 메서드, 생성자, toString 메서드 등과 같이 반복적으로 작성되는 코드

  • 주요 Lombok Annotation 예시
    • @Getter, @Setter
      • 해당 클래스의 모든 필드에 대한 게터와 세터를 자동생성
    • @ToString
      • 객체의 toString() 메서드를 자동생성
    • @NoArgsConstructor
      • 기본 생성자를 생성
    • @AllArgsConstructor
      • 모든 필드를 매개변수로 하는 생성자를 생성
    • @RequiredArgsConstructor
      • 필수(final) 필드만을 매개변수로 하는 생성자를 자동생성
    • @Slf4j
      • 클래스에 로그를 남기기 위한 Logger 객체를 자동생성
  • Spring Initializr
    • 스프링 부트(Spring Boot) 기반의 프로젝트를 매우 쉽고 빠르게 생성할 수 있도록 도와주는 웹 기반 도구 및 서비스
  • 의존성(Dependency)
    • 스프링 부트에서 의존성(Dependency)은 우리 프로젝트가 제대로 동작하기 위해 필요한 외부 라이브러리나 외부 코드를 의미
    • 다른 사람들이 만들어 놓은 편리한 기능(부품)을 가져와 조립해서 사용하는 것
    • Gradle을 주로 사용
      • build.gradle이라는 파일을 사용하며, 그루비(Groovy)코틀린(Kotlin)이라는 프로그래밍 언어를 사용해 작성
  • Maven Repository(메이븐 리포지토리)
    • 자바 라이브러리(JAR, 라이브러리, 플러그인 등)들을 모아두고 관리하는 온라인 저장소
    • MavenGradle보다 먼저 만들어졌기 때문에 Gradle Repository가 아니라 Maven Repository라고 부름
  • 서블릿(Servlet)
    • 서버에서 실행되어 클라이언트의 요청을 처리하고, 그 결과를 동적으로 생성하여 응답하는 자바 프로그램
    • 정적인 데이터가 아니라, 요청에 따라 다른 결과를 만들어내는 똑똑한 자바 클래스
    • 자바 웹 애플리케이션에서 특정 URL 요청에 대한 비즈니스 로직을 실행하는 핵심
    • 역할:
      • 클라이언트가 보낸 데이터(HTTP Request)를 읽고 해석
      • 조회, 계산 등 비즈니스 로직을 수행
      • 결과를 생성하여 클라이언트에게 전송
      • jakarta.servlet.http.HttpServlet 클래스를 상속받아 구현
  • 서블릿 컨테이너(Servlet Container)
    • 서블릿 클래스는 스스로 실행될 수 없음
    • 서블릿을 실행하고 관리하며 웹 서버와 통신하게 해주는 전문적인 환경이 필요 -> 이를 서블릿 컨테이너라고 함
    • 가장 대표적인 서블릿 컨테이너: 톰캣(Tomcat)
    • 역할:
      • 서블릿의 생명주기(생성, 실행, 소멸) 관리
      • HTTP 요청을 받아 서블릿에게 전달
      • 서블릿의 응답을 받아 클라이언트에게 전송
      • 동시에 여러 요청이 들어와도 문제없이 처리
    • @ServletComponentScan
      • 서블릿은 스프링 부트 표준이 아니기에 스프링 부트에서 탐지하지 못하기 때문에 이 어노테이션이 필요

챕터2 : Spring MVC

  • 서블릿의 문제점
    • 낮은 응집도
    • 강한 결합도
    • 반복적인 상용구 코드
  • MVC 패턴
    • 하나의 Servlet이 혼자 모든 것을 처리하던 문제를 해결하기 위해 애플리케이션의 코드를 세 가지 역할로 명확하게 나누는 설계 방식
    • Controller
      • 사용자의 HTTP 요청을 받아서 처리
      • @Controller가 붙은 클래스가 이 역할을 수행
    • Model
      • Controller에서 View로 데이터를 전달할 때 사용하는 객체
    • View
      • 사용자에게 보여지는 화면을 담당
  • Thymeleaf
    • 서버에서 HTML을 동적으로 만들어주는 자바 기반의 도구, 즉 템플릿 엔진
    • 역할: 자바 코드(스프링 컨트롤러)가 보내주는 데이터를 실제 HTML 코드와 결합하여, 내용이 채워진 완성된 웹 페이지를 생성
  • SSR
    • 서버가 웹 페이지에 필요한 모든 데이터를 채워 넣어 완벽하게 조립된 HTML 페이지를 브라우저에게 전달하는 방식
    • 서버에서 완성된 HTML을 통째로 주는 것
  • CSR
    • 서버가 거의 텅 빈 HTML 뼈대와 자바스크립트 파일만 보내주는 방식
    • 클라이언트에서 자바스크립트로 그 때 그 때 HTML을 그려내는 것

디자인패턴

  • 프론트 컨트롤러 패턴(Front Controller Pattern)
    • 모든 클라이언트 요청을 단일 진입점(Single Point of Entry)에서 처리하는 디자인 패턴
  • 어댑터 패턴 (Adapter Pattern)
    • 서로 다른 인터페이스를 가진 클래스들을 연결해주는 패턴
  • DispatcherServlet
    • 프론트 컨트롤러 패턴을 구현한 스프링 MVC의 핵심적인 프론트 컨트롤러

0개의 댓글