Algorithms/백준

[백준] '색종이' - Java

LEFT 2023. 7. 17. 15:14

<문제 제시>

<문제설명>
가로, 세로의 크기가 각각 100인 정사각형 모양의 흰색 도화지가 있다. 
이 도화지 위에 가로, 세로의 크기가 각각 10인 정사각형 모양의 검은색 색종이를 
색종이의 변과 도화지의 변이 평행하도록 붙인다. 
이러한 방식으로 색종이를 한 장 또는 여러 장 붙인 후 색종이가 붙은 
검은 영역의 넓이를 구하는 프로그램을 작성하시오.

<예시 입출력>


<문제 해결 과정>

검은 영역의 넓이를 구하는 것이므로 겹치는 부분은 차감해주어야한다.

Try 1) 

// 색종이의 수
int N = Integer.parseInt(br.readLine());

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

// INPUT : 2차원배열과 각 좌표
for(int i = 0; i < N; i++) {
    st = new StringTokenizer(br.readLine());

    for(int j = 0; j < 2; j++) {
        arr[i][j] = Integer.parseInt(st.nextToken());
    }
}
// 1차 테스트 : 2차원 배열 데이터 출력
System.out.println(Arrays.deepToString(arr));

// 2. 입력받은 x,y좌표로 넓이 구하기

// 기본적으로 색종이는 10x10크기를 가지므로 미리 전체크기를 넣어놓는다.
// 겹치는 부분만 차감하면 된다.
int sum = N * 100;

// 겹치는 부분 로직 구하기
// ?

겹치는 부분 로직을 구할때 각 행에서 10을 더해서 그것이 다음 행의 인덱스 안에 포함되면 
그것으로 겹치는 부분의 변 길이를 구하려했으나 감이 잡히지 않았다.


Answer 1) 

// x부터 10칸을 색칠해줌
for(int j = x; j < x+10; j++) {
    for(int k = y; k < y+10; k++) {

        // arr[j][k]의 값이 false일때,
        if(!arr[j][k]) {
            arr[j][k] = true; // true로 바꿔주고,
            black++; // 색칠된 부분은 넓이 = 칸의 개수 >> 칸의 개수 증가
        }
    }
}

boolean형 2차원 배열을 선언하고, true로 바꿔주어 색칠된 부분임을 표시한다.

겹치는 부분을 효과적으로 구하기 위해서는 boolean 배열을 선언 후 한번 색종이가 만들어진 곳은

체크되도록하여 그 체크된 부분의 크기만 구하면 된다.


<전체코드>

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

public class Main {

	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		
		int black = 0; // 색칠된 부분을 표시할 변수
		int N = Integer.parseInt(br.readLine());
		
		// 도화지 크기는 100이하로 주어졌다.
		boolean[][] arr = new boolean[101][101];
		
		for(int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			int x = Integer.parseInt(st.nextToken());
			int y = Integer.parseInt(st.nextToken());
			
			// x부터 10칸을 색칠해줌
			for(int j = x; j < x+10; j++) {
				for(int k = y; k < y+10; k++) {
					
					// arr[j][k]의 값이 false일때,
					if(!arr[j][k]) {
						arr[j][k] = true; // true로 바꿔주고,
						black++; // 색칠된 부분은 넓이 = 칸의 개수 >> 칸의 개수 증가
					}
				}
			}
		}
		
		for(int i = 0; i < arr.length; i++) {
			System.out.println(Arrays.toString(arr[i]));
		}
		System.out.print(black);
	}

}

그림으로 생각해서 어려울 것 같았으나, 겹치는 부분을 다시 boolean형으로 판단한다.


문제링크)
https://www.acmicpc.net/problem/2563

 

2563번: 색종이

가로, 세로의 크기가 각각 100인 정사각형 모양의 흰색 도화지가 있다. 이 도화지 위에 가로, 세로의 크기가 각각 10인 정사각형 모양의 검은색 색종이를 색종이의 변과 도화지의 변이 평행하도록

www.acmicpc.net