백준 문제풀이

2477. 참외밭 (자바, Java)

뮤츠 2022. 10. 10. 22:33

 면적을 구하는건 별거아닌데, 패턴 때문에 '어떻게하면 컴퓨터가 알아먹게 설명할 수 있을까?' 가 고민되는 문제.

일단 중요한 힌트는, 무조건 반시계방향으로 간다는 것. 어떤 점에서 출발하더라도, 방향이 고정되어있기에

방향을 전부 모아보면 모양을 유추할 수 있다.

예제 입력1은 ㄱ자 모양에서 우측 하단인 5시방향부터 출발하는데, 423131 순이다.

그렇다면 그 위의 점에서 출발한다면? 231314이다. 시작점만 달라지고 순서만 바뀌었다.

즉, ㄱ자모양은 1 2개, 2 1개, 3 2개, 4 1개가 나오는 꼴이다.

 

 다른 모양도 같은 식으로 카운팅이 가능하다. 따라서 map 자료구조를 통해 1~4까지 몇번 출현했는지 카운트해서 모양을 확정짓는다.

 

 그 후 넓이를 어떻게 구할까 생각해봤다. 처음에는 각각의 좌표를 구해줘서 계산하는 방법을 고민했는데, 컴퓨터한테 이 좌표를 어디에 위치해서 어떻게 계산하라 알려주는게 쉽지 않았다. 그래서, 차라리 offset을 이용해서, 입력값을 그대로 이용해 구해주는 방법을 이용했다.

 

 ㄱ자 모양에서 1개만 나오는건 2와 4다. 나는 2를 기준으로 잡았다. 2가 나오는 입력값의 offset을 0으로 잡고, 사각형을 두개로 쪼개 30*60 + 100*50 을 하면 참외밭의 면적을 구할 수 있다. 아참, 마지막에 k를 곱해주는걸 잊으면 안 된다.

따라서 6*2 배열로 입력값을 받고, 각 모양에서 1개만 있는 값을 기준으로 offset을 구해 각각 곱해주었다. 그런데 배열의 크기를 초과하는 경우가 존재할 수 있어서, 6으로 나눠준 나머지를 이용하였다. offset + 기준점의배열위치 가 6을 초과하면, 자연스레 6만큼 회전한 상대적인 값을 구할 수 있기 때문.

 

 이번엔 나도 헷갈려서 주석을 열심히 달았다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class Main {

	static int[][] input;

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		int k = Integer.parseInt(br.readLine());
		Map<Integer, Integer>count = new HashMap<>(); 
		// 방향 카운트를 위한 map자료형
		input = new int[6][2]; // 입력값을 받을 배열 


		for (int i=0; i<6; i++) {

			StringTokenizer st = new StringTokenizer(br.readLine()," ");
			int d = Integer.parseInt(st.nextToken()); // 방향
			int l = Integer.parseInt(st.nextToken()); // 길이
			count.put(d,count.getOrDefault(d, 0)+1);
			input[i][0] = d;
			input[i][1] = l;
			// 방향 카운트
		}

		int ans = 0;

		// if문을 통해, 방향 카운트에 따른 참외밭의 모양을 판별
		if (count.get(2)==1 && count.get(4)==1) {
			// ㄱ자모양
			for (int i=0; i<6; i++) {
				if (input[i][0] == 2) {
					// 1개뿐인 2방향 값을 이용하여 offset으로 모양을 유추
					System.out.println(ans(k, i));
				}
			}
		} else if (count.get(2)==1 && count.get(3)==1) {
			// 90도회전
			for (int i=0; i<6; i++) {
				if (input[i][0] == 2) {
					// 1개뿐인 2방향 값을 이용하여 offset으로 모양을 유추
					System.out.println(ans(k, i));
				}
			}
		} else if (count.get(1)==1 && count.get(3)==1) {
			// 180도회전, ㄴ자모양
			for (int i=0; i<6; i++) {
				if (input[i][0] == 1) {
					// 1개뿐인 2방향 값을 이용하여 offset으로 모양을 유추
					System.out.println(ans(k, i));
				}
			}
		} else if (count.get(1)==1 && count.get(4)==1) {
			// 270도회전
			for (int i=0; i<6; i++) {
				if (input[i][0] == 1) {
					// 1개뿐인 2방향 값을 이용하여 offset으로 모양을 유추
					System.out.println(ans(k, i));
				}
			}
		}
	}
	
	static int ans(int k, int i) {
		// offset을 이용하여 결과값을 계산하는 매소드
		return k * ((input[(i+1)%6][1] * input[(i+2)%6][1])
				+ (input[(i+4)%6][1] * input[(i+5)%6][1]));
	}
}