3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

解決!!AtCoder ABC234 D java クリア!!

Posted at

##解決しました!
java初心者のヤスです!
AtCoder ABC234 D をようやっと解決しました!

どこでつまづいて、どうやって解決したかをまとめています。
問題はこちら↓

##つまづいたところ
・split()でわざわざ全部読み込んでいた。
・配列とListの多様
・StringBuilder知らなかった。
・そもそもの考え方

##いまだにイマイチわからんこと
・平衡二分探索
・log回の概念

###split()でわざわざ全部読み込んでいた。

java
String[] NK = sc.nextLine().split(" ");
int N = Integer.parseInt(NK[0]);
int K = Integer.parseInt(NK[1]);

//中略

int numlist[] = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();

NとK改行された数列を読み込むコードですが...
これだと一行読み込んで、空白で分割して、変数に入れたり配列に一つ一つ入れていく作業をしていますが...

やっぱ作業量多い..なんかないかな..スクリーンショット 2022-01-22 16.34.19.png

あぁ〜!nextInt()使えばええのかぁ〜!
空白あっても使えるんか〜!
リファレンスに使えるって書いてある〜〜〜
あぁ〜〜

ということで使いました!変えたのがこちら↓

java
int N = sc.nextInt();
int K = sc.nextInt();
//中略
for(int i = 0; i < K; i++) {
	iQlist.add(sc.nextInt());
}

ということでだいぶ圧縮できた!
@yucatio  さんありがとうございました!

分割しなくていいし、intに変換しなくていいし、そもそも考え方で配列いらないし。

for文のところは配列からK個分をPriorityQueueにそのまま入れてます!

###配列とListの多様

当初は数字を一気に読み込んでsplit(" ");で空白区切りにして配列に入れ込んでInteger.ParthIntしてIntのListにいれて...

みたいに破滅的に面倒なことをしていました...

読み取りに関しては前述の通りで
List使いすぎ問題はPriorityQueueで解決しました!

こういう時PriorityQueueって便利ですね〜

@PondVillege さんめっちゃ参考になりました!ありがとうございました!
スクリーンショット 2022-01-22 17.40.24.png

やっていることは同じでもやっぱり処理速度違うもんなんだな...

###StringBuilder知らなかった

System.out.println();
の繰り返し出力が案外遅かったらしい。
詳しくはわかりませんが、1回1回メソッド?を呼び出してどうのこうの...といった理由みたいです。

ということで、StringBuilderをつかって数字を保持、最後にまとめて出力という形にしました!

保持の形と出力のコードはこちら↓

java
//PriorityQueueの先頭と改行コードを保持
ans.append(iQlist.peek() +  "\n");

//toStringを使って出力		
System.out.println(ans.toString());
		

###そもそもの考え方

データをこねくり回していたのが原因でした

入力値

一行ずつ読み取る

NとKをintに変換して変数に代入
数列は配列に全部代入

配列からK個分取り出して配列に代入

その配列の最小値を見つける

最小値を出力

最小値とK+1番目の数字を比べる

大きければ最小値を削除

K+1番目の数字を配列に追加

最小値出力
N番目まで繰り返し

というのを

入力

nextInt();でNとKにそれぞれ代入

nextInt();でK個分のみPriorityQueueに代入

先頭をStringBuilderに保持(最小値を保持)

★nextInt();でK+1....を読み込む

保持した最小値とK+1番目の数字を比べる

(小さい場合何もしない)
大きい場合
最小値削除

K+1番目を配列に追加

先頭を保持
★からN番目まで繰り返し

保持した数字を出力

といった感じです。
ポイントは
『数列全て配列に入れ込まなくても入力値つかえばええやん』
ということ
nextInt();の性質をもっと知っていれば思いついた考え方だったかなと!
配列やlistを無くしてPriorityQueue1つだけでできました!
(そりゃ早くなるわ)

###最後に
最後にクリアしたコードがこちら↓

java
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		//一行目の数字2つをNとKに代入
		int N = sc.nextInt();
		int K = sc.nextInt();
		
        
		Queue<Integer> iQlist = new PriorityQueue<Integer>();
		StringBuilder ans = new StringBuilder();
		
        //2行目の先頭からK個分をPriorityQueueに追加
        for(int i = 0; i < K; i++) {
			iQlist.add(sc.nextInt());
		}
        //最小値を保持
		ans.append(iQlist.peek() +  "\n");
		//K+1からNまで繰り返し
		for(int j = K; j < N; j++) {
			int kNext = sc.nextInt();

            //最小値とK+1...を比べる
			if(kNext > iQlist.peek()) {
                //先頭削除
				iQlist.poll();
                //K+1...を追加
				iQlist.add(kNext);
			}
            //最小値を保持
			ans.append(iQlist.peek() +  "\n");
		}
        //保持した数字を全部出力
		System.out.println(ans.toString());
		sc.close();
	}
}

ありがとうございました!!

データ構造とか平衡二分探索はもうすこしじかんがかかりそうやな。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?