숫자의 등장 횟수 카운트 = HashMap 이용
등장 횟수 기준 오름차순 = Value 기준 HashMap 오름차순 정렬 = Entry List 사용
0은 등장 횟수에서 제외
HashMap에 넣을 때 제외시킴
만약 빈칸 == 0 이라 생각하고 0이 나오면 반복문 종료 해버리면
두번째 행이 첫번째 행보다 길 경우, 열 정렬 때 두번째부터 값이 있는 첫번째에서 0을 만나서 종료해버림
// 5번째 열 정렬 시 뒤에 3이 있지만 0을 만나서 3을 카운트하지 못하고 종료해버림
2 1 1 2 0 0
1 1 2 1 3 1
3 3 0 0 0 0
이 처리 안해주면 "예제 4입력 4"에서 틀림
행의 길이는 길어질 수도, 짧아질 수도 있다 = HashMap에 배열 값 넣고 난 후 미리 0으로 초기화
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
public class Main_17140 {
static int r, c, k;
// 배열의 최대 길이가 100을 넘어가지 않게 미리 설정
static int MAX_SIZE = 100;
// 각 열의 길이 중 제일 큰 값 저장 변수
static int COL_SIZE = 3;
// 각 행의 길이 중 제일 큰 값 저장 변수
static int ROW_SIZE = 3;
// A 배열
static int[][] matrix;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String[] info = br.readLine().split(" ");
// r, c는 1부터 시작하여 -1
r = Integer.valueOf(info[0]) - 1;
c = Integer.valueOf(info[1]) - 1;
k = Integer.valueOf(info[2]);
// 행, 열이 100이 넘어가면 저장 안하니깐 미리 최대 길이까지 초기화시켜놓음
matrix = new int[MAX_SIZE][MAX_SIZE];
for (int i = 0; i < 3; i++) {
info = br.readLine().split(" ");
for (int j = 0; j < 3; j++) {
matrix[i][j] = Integer.valueOf(info[j]);
}
}
bw.write(solution() + "\n");
bw.flush();
bw.close();
}
static int solution() {
int time = 0;
while (matrix[r][c] != k) {
if (ROW_SIZE >= COL_SIZE) {
doRCalc();
} else {
doCCalc();
}
// 100초가 지났는데도 못찾으면 -1
if (++time > 100)
break;
}
return time > 100 ? -1 : time;
}
// 모든 행 정렬
static void doRCalc() {
// 각 행 정렬 시 열의 최대 크기가 달라짐
int newColSize = COL_SIZE;
for (int x = 0; x < ROW_SIZE; x++) {
// 각 수의 등장 횟수를 저장하기 위한 Map 생성
HashMap<Integer, Integer> dict = new HashMap<Integer, Integer>();
for (int y = 0; y < COL_SIZE; y++) {
// 0은 횟수 카운트에서 제외
if (matrix[x][y] == 0)
continue;
dict.put(matrix[x][y], dict.getOrDefault(matrix[x][y], 0) + 1);
// 행의 길이가 작아질 것을 대비하여 모두 0으로 초기화
matrix[x][y] = 0;
}
// Value(등장횟수)를 기준으로 Map 정렬
List<Entry<Integer, Integer>> dictEntry = mapSortByValue(dict);
// Map의 크기 = 등장하는 숫자의 개수
// Map의 크기 * 2 = 정렬된 행의 길이 = 열의 크기
// 정렬된 행의 길이가 100보다 클 경우 방지
int colSize = dictEntry.size() * 2 > 100 ? 100 : dictEntry.size() * 2;
for (int i = 0; i < colSize; i++) {
// 정렬된 순서대로 배열에 값 넣어줌
Entry<Integer, Integer> value = dictEntry.remove(0);
matrix[x][i] = value.getKey();
matrix[x][++i] = value.getValue();
}
// 정렬된 행의 길이 중에서 제일 큰 값 고름
newColSize = Math.max(newColSize, colSize);
}
// 열의 최대 크기 갱신
COL_SIZE = Math.max(ROW_SIZE, newColSize);
}
static void doCCalc() {
// 각 열 정렬 시 행의 최대 크기가 달라짐
int newRowSize = ROW_SIZE;
for (int y = 0; y < COL_SIZE; y++) {
HashMap<Integer, Integer> dict = new HashMap<Integer, Integer>();
for (int x = 0; x < ROW_SIZE; x++) {
if (matrix[x][y] == 0)
continue;
dict.put(matrix[x][y], dict.getOrDefault(matrix[x][y], 0) + 1);
matrix[x][y] = 0;
}
List<Entry<Integer, Integer>> dictEntry = mapSortByValue(dict);
int rowSize = dictEntry.size() * 2 > 100 ? 100 : dictEntry.size() * 2;
for (int i = 0; i < rowSize; i++) {
Entry<Integer, Integer> value = dictEntry.remove(0);
matrix[i][y] = value.getKey();
matrix[++i][y] = value.getValue();
}
newRowSize = Math.max(newRowSize, rowSize);
}
// 열의 길이 = 행의 사이즈
// 행의 최대 길이 갱신
ROW_SIZE = Math.max(ROW_SIZE, newRowSize);
}
static List<Entry<Integer, Integer>> mapSortByValue(HashMap<Integer, Integer> dict) {
// Map의 Entry를 담은 List 생성
List<Entry<Integer, Integer>> dictEntry = new ArrayList<Entry<Integer, Integer>>(dict.entrySet());
// Entry 정렬
Collections.sort(dictEntry, new Comparator<Entry<Integer, Integer>>() {
@Override
public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
// key : 숫자, value : 등장 횟수
// 등장 횟수 기준 오름차순
// 만약 횟수가 같으면
if (Integer.compare(o1.getValue(), o2.getValue()) == 0) {
// 숫자 기준 오름차순
return Integer.compare(o1.getKey(), o2.getKey());
}
return Integer.compare(o1.getValue(), o2.getValue());
}
});
return dictEntry;
}
}