LoginSignup
1
1

More than 1 year has passed since last update.

ABC263A~Dの解答[Java]

Posted at

はじめに

A~Cはコンテスト中に、Dは解説を見て解きました。Dまで解きたかったな・・・。

では、見ていきましょう。

A - Full House

問題文はこちら

A~Eをそれぞれ見ていっても良いですが、ソートして参照した方がなんとなく楽かなと思いました。
A~Eを配列に入れてソートし、card[0]==card[1]かつcard[3]==card[4]を満たしていて、かつcard[2]がcard[1]かcard[3]と等しければフルハウスになります(全部同じケースは無いと制約にあるのでこれで良い)。

A.java
class Main{
 
	static Library System = new Library(java.lang.System.in,java.lang.System.out);
 
	public static void main(String[] args)throws IOException{

		//A~Eを格納&ソート
		int[] card = System.in.nextInt(5);
		System.sort(card);

		//条件を満たしたらYes、満たさなければNo
		if(card[0]==card[1]&&card[3]==card[4]&&(card[1]==card[2]||card[2]==card[3]))
			System.out.println("Yes");
		else
			System.out.println("No");
		System.out.close();
	}
}

条件文の長さは同じですが、公式解説の方がスマートな考え方ですね。

B - Ancestor

問題文はこちら

P[N]から順に見ていけば良いです。
初期値を1代目にして、P[i]==1になるまでずっと繰り返しました。

B.java
class Main{
 
	static Library System = new Library(java.lang.System.in,java.lang.System.out);
 
	public static void main(String[] args)throws IOException{

		//N、Pの取得
		int N = System.in.nextInt();
		int[] P = new int[N+1];	
		for(int i=2;i<=N;i++)P[i]=System.in.nextInt();

		//初期値設定
		int answer = 1;
		int temp = P[N];

		//1までずっと繰り返す
		while(true){

			//1?
			if(temp==1){
				System.out.println(answer);
				break;
			}

			//まだ1じゃないなら次の値を見る
			answer++;
			temp = P[temp];
		}
		System.out.close();
	}
}

ちょっと問題文を理解するのに時間がかかってしまいましたが、まぁ許容範囲。

C - Monotonically Increasing

問題文はこちら

特に何も考えず再帰関数(DFS?)で実装しました。
昇順で調べるので出力する順番を考える必要はありません(面倒なので末尾スペースは許容)。

C.java
class Main{
 
	static Library System = new Library(java.lang.System.in,java.lang.System.out);

	//答えを格納するList
	static ArrayList<ArrayList<Integer>> answer = new ArrayList<ArrayList<Integer>>();
 
	public static void main(String[] args)throws IOException{

		//N、Mの取得
		int N = System.in.nextInt();
		int M = System.in.nextInt();
 
		//メソッドに丸投げ(N、Mは渡さなくても良かったな・・・)
		search(N,M,new ArrayList<Integer>());
 
		//順に出力
		for(ArrayList<Integer> temp1:answer){
			for(int temp2:temp1){
				System.out.print(temp2+" ");
			}
			System.out.println();
		}
		System.out.close();
	}

	//再帰
	public static void search(int stack,int limit,ArrayList<Integer> list){

		//終点か?
		if(stack==list.size()){

			//参照の値渡しを避けるため新しいListで
			ArrayList<Integer> ans = new ArrayList<Integer>();
			ans.addAll(list);
			answer.add(ans);
			return;
		}
		//初回も中に書いてみた
		if(list.size()==0){
			for(int i=1;i<=limit;i++){
				list.add(i);
				search(stack,limit,list);
				list.remove(list.size()-1);
			}
			return;
		}
		//次の値の候補を格納して全探索
		for(int i=list.get(list.size()-1)+1;i<=limit;i++){
			list.add(i);
			search(stack,limit,list);
			list.remove(list.size()-1);
		}
	}
}

実装に時間がかかってしまった・・・。力不足ですね。

D - Left Right Operation

問題文はこちら

公式解説まんまです。

ただ、g(N-i)というのがちょっと面倒だったのでg(k)ではなくg(N-k+1)として格納してあります。

D.java
class Main{
 
	static Library System = new Library(java.lang.System.in,java.lang.System.out);
 
	public static void main(String[] args)throws IOException{

		//各値の取得(L、Rは後々計算するときにオーバーフローするのでlong型で)
		int N = System.in.nextInt();
		long L = System.in.nextLong();
		long R = System.in.nextLong();
		int[] A = System.in.nextInt(N);
 
		//fを順に求める
		long[] f = new long[N+1];
		f[0] = 0;
		for(int i=1;i<=N;i++){
			f[i] = Math.min(f[i-1]+A[i-1],L*i);
		}
 
		//gも順に求める
		long[] g = new long[N+1];
		g[N] = 0;
		for(int i=N-1;i>=0;i--){
			g[i] = Math.min(g[i+1]+A[i],R*(N-i));
		}
 
		//各組合せで最小を探す
		long min = Long.MAX_VALUE;
		for(int i=0;i<=N;i++){
			min = Math.min(min,f[i]+g[i]);
		}

		//答えの出力
		System.out.println(min);
		System.out.close();
	}
}

詳しい考え方は公式解説に任せます(逃げ)。

感想

A:特に問題は無い。
B:同上。
C:手間取ってしまった・・・。
D:xのちょうど良いところとyのちょうど良いところを探せば良いと思っていたが、hackで見事にやられた。
って感じでした。

4完難しいですね・・・。精進しないと停滞するということが手に取るようにわかりました。

1
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
1
1