1. 문제
17140번: 이차원 배열과 연산
첫째 줄에 r, c, k가 주어진다. (1 ≤ r, c, k ≤ 100) 둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.
www.acmicpc.net
2. 접근방법
R연산과 C연산을 어떻게 풀어가느냐가 중요한 문제
연산을 하면 각 숫자의 갯수를 세고
갯수가 적으면서 숫자가 작은 순으로 정렬한 상태로
숫자 , 숫자갯수 , 숫자, 숫자갯수, ...
식으로 배열에 다시 집어 넣어줘야한다.
해야 하는일이
1. 숫자의 갯수를 세기
2. 세어진 숫자들로 다시 배열 조립하기
인데
처음에 2가지 일을 한번에 할 방법이 없을까 하다가 삽질 좀 하고
두가지 일을 한번에 할 수는 없구나! 를 깨달았다.
그래서 숫자의 갯수를 셀 때는 배열에 +1씩 해가면서 세고
모든 배열을 돌 필요 없도록
HashSet을 이용해 등장했던 숫자들을 저장한 뒤
HashSet에서 수를 꺼내고 배열에서 갯수를 꺼낸뒤 하나의 변수에 담아
Priority Queue에 저장한 뒤
pq에서 하나씩 뽑아 배열을 다시 조립하여 주었다.
그리고 100회까지는 검사를 하여야 한다는 점도 주의하자.
3. 자바 코드
package Gold;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
import java.util.TreeMap;
public class G4_17140이차원배열과연산 {
static int r, c, k;
static int rlen = 3, clen = 3;
static int map[][] = new int[100][100];
static TreeMap<Integer, Integer> numcnt;
static int cntarr[] = new int[101];
static class Point implements Comparable<Point> {
int key;
int value;
public Point(int key, int value) {
this.key = key;
this.value = value;
}
@Override
public int compareTo(Point o) {
if(this.value == o.value) {
return this.key - o.key;
}
return this.value - o.value;
}
}
public static void main(String[] args) throws Exception {
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());
for (int i = 0; i < 3; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < 3; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
int cycle = 0;
boolean flag = false;
while (cycle++ <= 100) {
if(map[r][c] == k) {
flag = true;
break;
}
if (rlen >= clen)
R();
else
C();
}
System.out.println(flag?cycle-1 : -1);
}
static void R() {
int maxidx = 0;
for (int i = 0; i < rlen; i++) {
HashSet<Integer> set = new HashSet<>();
PriorityQueue<Point> pq = new PriorityQueue<>();
cntarr = new int[101];
for (int j = 0; j < clen; j++) {
if(map[i][j] == 0)
continue;
cntarr[map[i][j]]++;
set.add(map[i][j]);
map[i][j] = 0;
}
for(int k : set)
pq.add(new Point(k,cntarr[k]));
int idx = 0;
while(!pq.isEmpty() && idx < 100) {
Point now = pq.poll();
map[i][idx] = now.key;
if(idx+1 >= 100)
break;
map[i][idx+1] = now.value;
idx +=2;
}
maxidx = Math.max(maxidx, idx);
}
clen = maxidx;
}
static void C() {
int maxidx = 0;
for (int j = 0; j < clen; j++) {
HashSet<Integer> set = new HashSet<>();
PriorityQueue<Point> pq = new PriorityQueue<>();
cntarr = new int[101];
for (int i = 0; i < rlen; i++) {
if(map[i][j] == 0)
continue;
cntarr[map[i][j]]++;
set.add(map[i][j]);
map[i][j] = 0;
}
for(int k : set)
pq.add(new Point(k,cntarr[k]));
int idx = 0;
while(!pq.isEmpty() && idx < 100) {
Point now = pq.poll();
map[idx][j] = now.key;
if(idx+1 >= 100)
break;
map[idx+1][j] = now.value;
idx +=2;
}
maxidx = Math.max(maxidx, idx);
}
rlen = maxidx;
}
}
4. 마치며
두 가지일을 한번에 처리하지 못할까 고민하느라 시간이 많이 든 문제였다.
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
[백준] 20127 Y-수열 (0) | 2021.01.18 |
---|---|
[백준] 2151 거울설치 (0) | 2021.01.17 |
[백준] 5014 스타트링크 (0) | 2021.01.13 |
[백준] 19584 난개발 (0) | 2021.01.02 |
[백준] 20440 니가 싫어 싫어 너무 싫어 싫어 오지 마 내게 찝쩍대지마 (0) | 2020.12.31 |