[SWEA] 파리퇴치 3 (Java)

Hazel·2025년 2월 16일

문제

N x N 배열 안의 숫자는 해당 영역에 존재하는 파리의 개체 수를 의미한다.

파리 킬러 스프레이를 한 번만 뿌려 최대한 많은 파리를 잡으려고 한다. 스프레이의 노즐이 + 형태로 되어있어, 스프레이는 + 혹은 x 형태로 분사된다. 스프레이를 M의 세기로 분사하면 노즐의 중심이 향한 칸부터 각 방향으로 M칸의 파리를 잡을 수 있다.
다음은 M=3 세기로 스프레이르 분사한 경우 파리가 퇴치되는 칸의 예로, +또는 x 중 하나로 분사된다. 뿌려진 일부가 영역을 벗어나도 상관없다.

한 번에 잡을 수 있는 최대 파리수를 출력하라.

제약 사항

  1. N 은 5 이상 15 이하이다.
  2. M은 2 이상 N 이하이다.
  3. 각 영역의 파리 갯수는 30 이하 이다.

입력

가장 첫 줄에는 테스트 케이스의 개수 T가 주어지고, 그 아래로 각 테스트 케이스가 주어진다.
각 테스트 케이스의 첫 번째 줄에 N 과 M 이 주어지고,
다음 N 줄에 걸쳐 N x N 배열이 주어진다.

최종 코드

import java.util.Scanner;

public class Solution {

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

    static int[] cx = {-1, -1, 1, 1};
    static int[] cy = {-1, 1, -1, 1};

    public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);

        int T = sc.nextInt();

        for(int t = 1; t <= T; t++){

            int N = sc.nextInt();
            int M = sc.nextInt();

            int[][] arr = new int[N][N];

            for(int i=0; i<N; i++){
                for(int j=0; j<N; j++){
                    arr[i][j] = sc.nextInt();
                }
            }

            // 가로세로 최대값
            int maxSum1 = Integer.MIN_VALUE;
            for(int i=0; i<N; i++){
                for(int j=0; j<N; j++){
                    int sum1 = arr[i][j];
                    for(int round=1; round < M; round ++){
                        for(int a = 0; a<4; a++){
                            int nx = i + round * dx[a];
                            int ny = j + round * dy[a];

                            if(nx>=0 && nx<N && ny>=0 && ny<N){
                                sum1 += arr[nx][ny];
                            }
                        }
                        maxSum1 = Math.max(maxSum1, sum1);
                    }

                }
            }

            // 대각선 최대값
            int maxSum2 = Integer.MIN_VALUE;
            for(int i=0; i<N; i++){
                for(int j=0; j<N; j++){
                    int sum2 = arr[i][j];
                    for(int round=1; round < M; round ++){
                        for(int a =0 ; a<4; a++){
                            int ncx = i + round * cx[a];
                            int ncy = j + round * cy[a];

                            if(ncx>=0 && ncx<N && ncy>=0 && ncy<N){
                                sum2 += arr[ncx][ncy];
                            }
                        }
                        maxSum2 = Math.max(maxSum2, sum2);
                    }

                }
            }

            int result = 0;
            result  = Math.max(maxSum1, maxSum2);
            System.out.println("#" + t + " " + result);
        }

        sc.close();
    }
}

델타 탐색을 이용해서 풀어야 되는 문제.
첨에 했던 실수는 배열 밖으로 값이 넘어가는지 체크하는 if문 제대로 안 적어준 것과
입력 받은 M번까지 바깥으로 뻗어나갈 때 round = 0부터로 조건을 준 것.
자잘한 실수가 너무 많다...ㅠㅜ

profile
이것저것 학습 기록장

0개의 댓글