[알고리즘][X] 배열 복원하기

2024. 1. 23. 19:22알고리즘 풀이/Java

https://www.acmicpc.net/problem/16967

 

16967번: 배열 복원하기

크기가 H × W인 배열 A와 두 정수 X와 Y가 있을 때, 크기가 (H + X) × (W + Y)인 배열 B는 배열 A와 배열 A를 아래로 X칸, 오른쪽으로 Y칸 이동시킨 배열을 겹쳐 만들 수 있다. 수가 겹쳐지면 수가 합쳐

www.acmicpc.net

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer stringTokenizer = new StringTokenizer(bufferedReader.readLine(), " ");

        int H = Integer.parseInt(stringTokenizer.nextToken());
        int W = Integer.parseInt(stringTokenizer.nextToken());
        int X = Integer.parseInt(stringTokenizer.nextToken());
        int Y = Integer.parseInt(stringTokenizer.nextToken());

        int[][] B = new int[H+X][W+Y];
        for (int i = 0; i < H + X; i++) {
            stringTokenizer = new StringTokenizer(bufferedReader.readLine(), " ");
            for (int j = 0; j < W + Y; j++) {
                B[i][j] = Integer.parseInt(stringTokenizer.nextToken());
            }
        }

        int[][] A = new int[H][W];
        for (int i = 0; i < H; i++) {
        	for (int j = 0; j < W; j++) {
        		A[i][j] = -1;
        	}
        }
        for (int i = 0; i < X; i++) {
        	for (int j = 0; j < W; j++) {
        		A[i][j] = B[i][j];
        	}
        }
        
        for (int i = X; i < H; i++) {
        	for (int j = 0; j < Y; j++) {
        		A[i][j] = B[i][j];
        	}
        }
        
        
        for (int i = X; i < H; i++) {
        	for (int j = W; j < W+Y; j++) {
        		A[i-(X)][j-(Y)] = B[i][j];
        	}
        }
        
        for (int i = H; i < H + X; i++) {
        	for (int j = Y; j < W; j++) {
        		A[i-(X)][j-(Y)] = B[i][j];
        	}
        }
        
        for (int i = X; i < H; i++) {
        	for (int j = Y; j < W; j++) {
        		if (A[i][j] == -1) {
        			A[i][j] = B[i][j] - A[i-X][j-Y];
        		} else {
        			A[i-X][j-Y] = B[i][j] - A[i][j];
        		}
        		
        	}
        }
        
        for (int i =0; i < H; i++) {
        	for (int j = 0; j < W; j++) {
        		System.out.print(A[i][j] + " ");
        	}
        	System.out.println();
        }
    }
}

나의 풀이

- 구할 수 있는 값을 먼저 구하고 겹치는 값을 구한 값으로부터 빼서 모르는 값을 구하도록 했다.

- 그런데 그 방법이 수학적으로 유효한다는 것은 검증을 못했다.

 

아래는 리팩토링한 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer stringTokenizer = new StringTokenizer(bufferedReader.readLine(), " ");

        int H = Integer.parseInt(stringTokenizer.nextToken());
        int W = Integer.parseInt(stringTokenizer.nextToken());
        int X = Integer.parseInt(stringTokenizer.nextToken());
        int Y = Integer.parseInt(stringTokenizer.nextToken());

        int[][] B = new int[H+X][W+Y];
        for (int i = 0; i < H + X; i++) {
            stringTokenizer = new StringTokenizer(bufferedReader.readLine(), " ");
            for (int j = 0; j < W + Y; j++) {
                B[i][j] = Integer.parseInt(stringTokenizer.nextToken());
            }
        }

      
        int[][] A = new int[H][W];
        initRectangle(A, B, H, W, X, Y);
        findOriginalValueFromNotMovingRectangle(A, B, H, W, X, Y);
        findOriginalValueFromMovingRectangle(A, B, H, W, X, Y);
        findOriginalValueFromTwoRectangles(A, B, H, W, X, Y);
        displayOriginalRectangle(A, B, H, W, X, Y);

    }

    private static void initRectangle(int[][] A, int[][] B, int H, int W, int X, int Y) {
      for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
          A[i][j] = -1;
        }
      }
    }
  
    private static void findOriginalValueFromNotMovingRectangle(int[][] A, int[][] B, int H, int W, int X, int Y) {
      for (int i = 0; i < X; i++) {
        for (int j = 0; j < W; j++) {
          A[i][j] = B[i][j];
        }
      }

      for (int i = X; i < H; i++) {
        for (int j = 0; j < Y; j++) {
          A[i][j] = B[i][j];
        }
      }
    }

  private static void findOriginalValueFromMovingRectangle(int[][] A, int[][] B, int H, int W, int X, int Y) {
    for (int i = X; i < H; i++) {
      for (int j = W; j < W+Y; j++) {
        A[i-(X)][j-(Y)] = B[i][j];
      }
    }

    for (int i = H; i < H + X; i++) {
      for (int j = Y; j < W; j++) {
        A[i-(X)][j-(Y)] = B[i][j];
      }
    }
  }

  private static void findOriginalValueFromTwoRectangles(int[][] A, int[][] B, int H, int W, int X, int Y) {
    for (int i = X; i < H; i++) {
      for (int j = Y; j < W; j++) {
        if (A[i][j] == -1) {
          A[i][j] = B[i][j] - A[i-X][j-Y];
        } else {
          A[i-X][j-Y] = B[i][j] - A[i][j];
        }

      }
    }
  }

  private static void displayOriginalRectangle(int[][] A, int[][] B, int H, int W, int X, int Y) {
    for (int i =0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        System.out.print(A[i][j] + " ");
      }
      System.out.println();
    }
  }
}