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);
}
}