Article Image
Article Image
read

문제

크기가 N×M인 배열 A가 있을 때, 다음과 같은 방법을 이용해서 크기가 (N-1)×(M-1)인 배열 B를 만들 수 있다.

  • B[i][j] = A[i][j] + A[i+1][j] + A[i+1][j+1] + A[i][j+1] (1 ≤ i < N, 1 ≤ j < M)

배열의 값은 배열의 모든 원소를 합한 값이다.

배열 A에서 임의의 두 행이나 임의의 두 열의 위치를 교환할 수 있다. 배열 A에서 교환을 최대 1번 수행해서 만들 수 있는 배열 B의 값의 최댓값을 구해보자.

입력

첫째 줄에 배열 A의 크기 N, M이 주어진다. 둘째 줄부터 N개의 줄에 배열의 원소가 주어진다. 배열은 정수로만 이루어져 있다.

출력

만들 수 있는 배열 B의 값 중 최댓값을 출력한다.

제한

  • 2 ≤ N, M ≤ 1,000
  • -1,000 ≤ Ai,j ≤ 1,000

예제 입력 1

3 3
9 8 7
3 2 1
6 5 4

예제 출력 1

92

예제 입력 2

3 4
1 2 1 1
2 1 1 2
2 1 1 1

예제 출력 2

34

예제 입력 3

3 3
1 1 1
1 2 1
1 1 1

예제 출력 3

20

풀이

이 문제는 이 문제는 특별한 알고리즘을 이용해서 푸는 문제는 아니다. 그러나 주어진 조건과 문제 내용을 토대로 모든 경우의 수를 구하는 게 아닌 최적의 방법을 생각해서 풀어야 한다.

import java.io.InputStreamReader;
import java.io.BufferedReader;

public class Main {
    static int[][] A;
    static int N;
    static int M;
    static int max;

    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input = br.readLine().split(" ");
        N = Integer.parseInt(input[0]);
        M = Integer.parseInt(input[1]);
        A = new int[N][M];
        max = 0;

        for(int i=0; i<N; i++) {
            input = br.readLine().split(" ");
            for(int j=0; j<M; j++)
                A[i][j] = Integer.parseInt(input[j]);
        }

        for(int i=0; i<N-1; i++) {
            for (int j=0; j<M-1; j++) {
                max += (A[i][j] + A[i+1][j] + A[i+1][j+1] + A[i][j+1]);
            }
        }

        if(N>2) {
            int min_row = -1;
            int sum_row = Integer.MAX_VALUE;

            for(int i=1; i<N-1; i++) {
                int sum = 0;
                for (int j=0; j<M; j++) {
                    sum += A[i][j];
                }
                sum = 4*sum - 2*(A[i][0] + A[i][M-1]);

                if(sum<sum_row) {
                    sum_row = sum;
                    min_row = i;
                }
            }

            rotate(min_row, 0, true);
            rotate(min_row, N-1, true);

        }

        if(M>2) {
            int min_col = -1;
            int sum_col = Integer.MAX_VALUE;

            for(int j=1; j<M-1; j++) {
                int sum = 0;
                for (int i=0; i<N; i++) {
                    sum += A[i][j];
                }
                sum = 4*sum - 2*(A[0][j] + A[N-1][j]);

                if(sum<sum_col) {
                    sum_col = sum;
                    min_col = j;
                }
            }

            rotate(min_col, 0, false);
            rotate(min_col, M-1, false);
        }

        System.out.println(max);
    }

    public static void rotate(int x, int y, boolean flag) {
        int[][] a = new int[N][M];

        if(flag) {
            for(int i=0; i<N; i++) {
                for(int j=0; j<M; j++) {
                    if(i==x)
                        a[y][j] = A[i][j];

                    else if(i==y)
                        a[x][j] = A[i][j];

                    else
                        a[i][j] = A[i][j];
                }
            }
        }

        else {
            for(int i=0; i<N; i++) {
                for(int j=0; j<M; j++) {
                    if(j==x)
                        a[i][y] = A[i][j];

                    else if(j==y)
                        a[i][x] = A[i][j];

                    else
                        a[i][j] = A[i][j];
                }
            }
        }

        int sum = 0;

        for(int i=0; i<N-1; i++) {
            for (int j=0; j<M-1; j++) {
                sum += (a[i][j] + a[i+1][j] + a[i+1][j+1] + a[i][j+1]);
            }
        }
        max = Math.max(sum, max);
    }
}
Blog Logo

pss407


Published

Image

pss's GitHub 블로그

Welcome my blog!

Back to Overview