2 D配列と演算(17140)
34549 ワード
1.質問
質問リンク
説明:
サイズ3×3人の列Aがある.配列のインデックスは1から始まります.1秒ごとに演算が配列に適用されます.
例えば,[3,1,1]では3が1回,1が2回出現する.したがって,並べ替えの結果は[3,1,2]であった.この配列では、3が1番、1が2番、2が1番で登場します.再ソートは[2,1,3,1,2]になります.
ソート結果を配列に戻すと、行または列のサイズが異なる場合があります.R演算では、最大行に応じてすべての行のサイズが変更されます.C演算では、最大列に基づいてすべての列のサイズが変更されます.行または列のサイズが大きくなる場合は、0を入力します.数値をソートする場合は、0を無視します.例えば、[3,2,0,0]を並べ替えた結果は、[3,2]を並べ替えた結果と同じである.
行または列のサイズが100を超える場合、最初の100以外の行または列は破棄されます.
配列Aの数字とr,c,kが与えられたとき,A[r][C]の値がkとなる最小時間を求める.
入力
第1行はr,c,kを与える.(1 ≤ r, c, k ≤ 100)
2行目から3行目にAで与えられた数字を並べます.配列Aの数字は100以下の自然数である.
しゅつりょく
演算の最小時間を出力し、A[r][C]の値をkとする.100秒経過してもA[r][c]=kでない場合、−1が出力される.
2.解答
2-1. 条件
2-2. に答える
一見、この問題は難しそうに見えるが、ちょっとした工夫さえすれば、簡単に解決できる.
計画1-必要な変数を宣言します.
// 계획1 - 필요한 변수 선언합니다.
int curR = 3; // 현재 행의 개수
int curC = 3; // 현재 열의 개수
int ans = -1;
int[][] A = new int[100][100]; // 100을 넘어가면 버리기 때문에 100 x 100의 배열을 선언했습니다.
int[] cnt = new int[101]; // 수의 등장 횟수를 세는 배열
最初に必要な変数を宣言するプロセスは非常に重要です.「どうやって問題に近づくの?」で行ないます.
実施の難しさは千差万別で、これは方法にかかっている.
私は2-1で指定した条件のうち、
100
を超える条件で残りの条件を放棄しました.100 x 100
の2 Dアレイのみを宣言し、問題の複雑さを低減しました.この条件がない場合は、メモリを動的に割り当て、実装するために
List
が宣言されている可能性があります.では、実現の難しさはかなり向上したのではないでしょうか.
そのため、問題をよりよく読み、それに応じて問題に簡単にアクセスする方法を常に見つけなければなりません.
計画2-カウントソート演算を実行します.
// 개수가 커지는 순에서 수가 커지는 순으로 정렬
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
実はこれがコア[수, 수의 등장 횟수]
を優先順位キューに入れ、問題の要件に従ってソートします.計画3—最大100回のR、C演算を行う.
この部分を完全なコードでチェックしましょう.
3.完全なコード
import java.util.PriorityQueue;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
// 계획1 - 필요한 변수들을 선언합니다.
int curR = 3; // 현재 행의 개수
int curC = 3; // 현재 열의 개수
int ans = -1;
int[][] A = new int[100][100]; // 100을 넘어가면 버리기 때문에 100 x 100의 배열을 선언했습니다.
int[] cnt = new int[101]; // 수의 등장 횟수를 세는 배열
// 계획2 - 수의 정렬 연산을 구현합니다.
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[1] == b[1] ? a[0] - b[0] : a[1] - b[1]);
StringTokenizer stk = new StringTokenizer(br.readLine());
int R = Integer.parseInt(stk.nextToken()) - 1;
int C = Integer.parseInt(stk.nextToken()) - 1;
int K = Integer.parseInt(stk.nextToken());
for (int i = 0; i < 3; i++) {
stk = new StringTokenizer(br.readLine());
for (int j = 0; j < 3; j++) {
A[i][j] = Integer.parseInt(stk.nextToken());
}
}
// 계획3 - 최대 100번의 R, C연산을 진행합니다.
for (int i = 0; i <= 100; i++) {
// 답을 찾았을 때
if (A[R][C] == K) {
ans = i;
break;
}
// R연산
if (curR >= curC) {
int nextC = -1; // R연산으로 인해 바뀔 열의 길이
for (int j = 0; j < curR; j++) {
// 한 행에 대하여 수의 등장 횟수를 셉니다.
for (int k = 0; k < curC; k++) {
if (A[j][k] != 0) {
cnt[A[j][k]]++;
}
}
// 등장한 수들을 우선순위큐에 넣습니다.
for (int k = 1; k <= 100; k++) {
if (cnt[k] != 0) {
pq.add(new int[] {k, cnt[k]});
cnt[k] = 0; // 다시 0으로 초기화
}
}
// 다음 열의 길이는 [수, 수의 등장 횟수], [수, 수의 등장 횟수]를
// [수, 수의 등장 횟수, 수, 수의 등장 횟수]로 평탄화 시켜야 하니까 pq.size() * 2가 됩니다.
nextC = Math.max(nextC, pq.size() * 2);
int idx = 0;
// 정렬한 결과를 현재 행에 덮어씌웁니다.
while (!pq.isEmpty()) {
int[] n = pq.poll();
A[j][idx++] = n[0];
A[j][idx++] = n[1];
}
// 남은 부분은 0으로 초기화 합니다.
for (int k = idx; k <= curC; k++) {
A[j][k] = 0;
}
}
// 100 이후는 버립니다.
curC = Math.min(nextC, 100);
}
// C연산
else {
int nextR = -1;
for (int j = 0; j < curC; j++) {
for (int k = 0; k < curR; k++) {
if (A[k][j] != 0) {
cnt[A[k][j]]++;
}
}
for (int k = 1; k <= 100; k++) {
if (cnt[k] != 0) {
pq.add(new int[] {k, cnt[k]});
cnt[k] = 0;
}
}
nextR = Math.max(nextR, pq.size() * 2);
int idx = 0;
while (!pq.isEmpty()) {
int[] n = pq.poll();
A[idx++][j] = n[0];
A[idx++][j] = n[1];
}
for (int k = idx; k <= curR; k++) {
A[k][j] = 0;
}
}
curR = Math.min(nextR, 100);
}
}
bw.write(ans + "");
bw.close();
}
}
Reference
この問題について(2 D配列と演算(17140)), 我々は、より多くの情報をここで見つけました https://velog.io/@front/백준-이차원-배열과-연산-17140テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol