はじめに
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]と等しければフルハウスになります(全部同じケースは無いと制約にあるのでこれで良い)。
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になるまでずっと繰り返しました。
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?)で実装しました。
昇順で調べるので出力する順番を考える必要はありません(面倒なので末尾スペースは許容)。
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)として格納してあります。
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完難しいですね・・・。精進しないと停滞するということが手に取るようにわかりました。