본문 바로가기
알고리즘/백준

[Java] BOJ 17140번 이차원 배열과 연산

by 컴공맨 2021. 9. 9.
 

17140번: 이차원 배열과 연산

첫째 줄에 r, c, k가 주어진다. (1 ≤ r, c, k ≤ 100) 둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.

www.acmicpc.net


풀이

문제에서 요구한대로 코드를 작성하여 해결했습니다.

자세한 내용은 코드의 주석을 참고해주세요.


코드

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

public class Main {
	public static class Info implements Comparable<Info> {
		int num, cnt;

		public Info(int num, int cnt) {
			this.num = num;
			this.cnt = cnt;
		}
		
		@Override
		public int compareTo(Info o) {
			// 문제의 조건에서 나온 횟수가 많은 순으로 정렬을 시킨다
			int diff = Integer.compare(this.cnt, o.cnt);
			
			// 만약 나온 횟수가 같다면 숫자가 큰 순으로 정렬을 시킨다.
			return (diff == 0) ? Integer.compare(this.num, o.num) : diff;
		}
	}
	public static int r, c, k, maxR, maxC, answer;
	public static int[][] arr;
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		
		r = Integer.parseInt(st.nextToken()) - 1;
		c = Integer.parseInt(st.nextToken()) - 1;
		k = Integer.parseInt(st.nextToken());
		
		arr = new int[100][100];
		
		for (int i = 0; i < 3; ++i) {
			st = new StringTokenizer(br.readLine(), " ");
			
			for (int j = 0; j < 3; ++j) {
				arr[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		
		// 처음 시작때 최대 행과 열은 3
		maxR = 3;
		maxC = 3;
		
		answer = getTime();
		
		System.out.println(answer);
	}
	
	public static int getTime() {
		int time = 0;
		
		// 배열의 (r, c) 위치의 값이 k가 아니고 time이 100을 넘지 않을때까지 반복
		while (arr[r][c] != k && time <= 100) {
			// 문제의 조건에 따라 현재 배열의 R이 길면 R 함수로
			// 현재 배열의 C가 길면 C 함수로 보낸다.
			if (maxR >= maxC) {
				R();
			}
			else {
				C();
			}
			
			// 처리를 했으므로 시간 +1
			time++;
		}
		
		// 만약 time이 100이넘는다면 -1을 아니라면 시간을 그대로 리턴
		return (time > 100) ? -1 : time;
	}
	
	public static void R() {
		// 가장 긴 길이를 저장
		int maxCol = maxC;
		
		for (int i = 0; i < maxR; ++i) {
			// 맵을 사용하여 숫자의 나온 횟수를 구한다.
			Map<Integer, Integer> map = new HashMap<>();
			
			for (int j = 0; j < maxC; ++j) {
				// 0이라면 숫자의 개수를 셀 필요가 없으므로 다음 숫자가 0이 아닌 수일 수 있기에 계속 탐색
				if (arr[i][j] == 0) {
					continue;
				}
				
				// 만약 맵에 포함된 숫자라면 기존 cnt에 +1을 아니라면 1을 맵에 넣는다
				if (map.containsKey(arr[i][j])) {
					map.put(arr[i][j], map.get(arr[i][j]) + 1);
				}
				else {
					map.put(arr[i][j], 1);
				}
			}
			
			// 정렬을 우선순위 큐를 사용해 수행
			PriorityQueue<Info> pq = new PriorityQueue<>();
			
			// map에 든 값들을 pq에 삽입
			for (int num : map.keySet()) {
				pq.add(new Info(num, map.get(num)));
			}
			
			int col = 0;
			// 문제의 조건에 의해 배열의 길이는 100이 넘어가면 안되므로 100까지만 반복
			while (!pq.isEmpty() && col < 100) {
				Info info = pq.poll();
				
				arr[i][col++] = info.num;
				arr[i][col++] = info.cnt;
			}
			
			// 가장 긴 길이를 저장한다.
			if (maxCol < col) {
				maxCol = col;
			}
			else {
				// 가장 긴 길이가 아니라면 오히려 기존의 길이보다 짧아졌을 수 도 있기 때문에
				// 짧아진 길이만큼 그 공간을 0으로 만들어 준다.
				for (int j = col; j < maxC; ++j) {
					arr[i][j] = 0;
				}
			}
		}
		
		// 다음 R함수나 C함수를 위해 현재까지 구한 가장 긴 길이를 저장한다.
		maxC = maxCol;
	}
	
	public static void C() {
		// 가장 긴 길이를 저장
		int maxRow = maxR;
		
		for (int i = 0; i < maxC; ++i) {
			// 맵을 사용하여 숫자의 나온 횟수를 구한다.
			Map<Integer, Integer> map = new HashMap<>();
			
			for (int j = 0; j < maxR; ++j) {
				// 0이라면 숫자의 개수를 셀 필요가 없으므로 다음 숫자가 0이 아닌 수일 수 있기에 계속 탐색
				if (arr[j][i] == 0) {
					continue;
				}
				
				// 만약 맵에 포함된 숫자라면 기존 cnt에 +1을 아니라면 1을 맵에 넣는다
				if (map.containsKey(arr[j][i])) {
					map.put(arr[j][i], map.get(arr[j][i]) + 1);
				}
				else {
					map.put(arr[j][i], 1);
				}
			}
			
			// 정렬을 우선순위 큐를 사용해 수행
			PriorityQueue<Info> pq = new PriorityQueue<>();
			
			// map에 든 값들을 pq에 삽입
			for (int num : map.keySet()) {
				pq.add(new Info(num, map.get(num)));
			}
			
			int row = 0;
			// 문제의 조건에 의해 배열의 길이는 100이 넘어가면 안되므로 100까지만 반복
			while (!pq.isEmpty() && row < 100) {
				Info info = pq.poll();
				
				arr[row++][i] = info.num;
				arr[row++][i] = info.cnt;
			}
			
			if (maxRow < row) {
				maxRow = row;
			}
			else {
				// 가장 긴 길이가 아니라면 오히려 기존의 길이보다 짧아졌을 수 도 있기 때문에
				// 짧아진 길이만큼 그 공간을 0으로 만들어 준다.
				for (int j = row; j < maxR; ++j) {
					arr[j][i] = 0;
				}
			}
		}
		
		// 다음 R함수나 C함수를 위해 현재까지 구한 가장 긴 길이를 저장한다.
		maxR = maxRow;
	}
}

 

GitHub - pyo7410/Algorithm: 1일 1커밋을 목표로!

1일 1커밋을 목표로! Contribute to pyo7410/Algorithm development by creating an account on GitHub.

github.com

 

'알고리즘 > 백준' 카테고리의 다른 글

[Java] BOJ 17825번 주사위 윷놀이  (0) 2021.09.14
[Java] BOJ 17822번 원판 돌리기  (0) 2021.09.10
[Java] BOJ 2661번 좋은수열  (0) 2021.09.07
[Java] BOJ 5427번 불  (0) 2021.09.06
[Java] BOJ 2638번 치즈  (0) 2021.09.03