はじめに
D以外はコンテスト中に書いたコードなので、若干汚いかもしれません。ご了承ください。
では解説していきます。
A - Six Characters
問題文はこちら
長さが6になるまでfor文でprintlnしてやればACが取れます。
import java.util.*;
class Main{
static Scanner sc = new Scanner(System.in);
public static void main(String[] args){
//文字列の取得
String str = read();
//6÷(文字列の長さ)回出力する
for(int i=0;i<6/str.length();i++){
System.out.print(str);
}
//最後改行して終了
retE("");
}
//旧テンプレ
public static void retE(String ret){System.out.println(ret);System.exit(0);}
public static String read(){return sc.next();}
}
特に難しくはないですね。
B - At Most 3 (Judge ver.)
問題文はこちら
1~3個を選んだときの数字をboolean型配列で管理してtrueの数字を最後に出力してやれば良さそうです。
import java.util.*;
class Main{
static Scanner sc = new Scanner(System.in);
public static void main(String[] args){
//N、Wの取得
int N = readI();
int W = readI();
//W以下の数字を作れるか管理する配列
boolean[] isExist = new boolean[W+1];
//各おもり受け取り用配列
int[] A = new int[N];
for(int i=0;i<N;i++){
A[i] = readI();
if(A[i]<=W)
isExist[A[i]] = true; //一個で作れる数字を格納
}
//二個で作れる数字を全探索
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(i==j)
continue;
int temp = A[i]+A[j];
if(temp<=W)
isExist[temp] = true;
}
}
//三個で作れる数字を全探索
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
for(int k=0;k<N;k++){
if(i==j||i==k||j==k)
continue;
int temp = A[i]+A[j]+A[k];
if(temp<=W)
isExist[temp] = true;
}
}
}
int count = 0;
//trueの数を数える
for(int i=0;i<isExist.length;i++){
if(isExist[i])
count++;
}
//trueの数を返して終了
retE(count);
}
//旧テンプレ
public static void retE(int ret){System.out.println(ret);System.exit(0);}
public static int readI(){return sc.nextInt();}
}
最初は全部書いちゃって良かったのかな…て思いましたがACだったので良かったです。
C - Poem Online Judge
問題文はこちら
重複が少々厄介ですが、とりあえずHashSetに突っ込んでサイズが変わらなければ愚直に調べ、サイズが変わるようであればすでに提出された文字列を管理するリストを作って最高点を調べます。
import java.util.*;
class Main{
static Scanner sc = new Scanner(System.in);
public static void main(String[] args){
//情報の取得
int N = readI();
String[] S = new String[N];
int[] T = new int[N];
for(int i=0;i<N;i++){
S[i] = read();
T[i] = readI();
}
//重複無し?
if(new ArrayList<String>(new HashSet<String>(Arrays.asList(S))).size()==N){
int max = 0;
int answer = 0;
//重複が無いので普通に最大値のインデックスを全探索
for(int i=0;i<N;i++){
if(max<T[i]){
max = T[i];
answer = i+1;
}
}
//答えを出力して終了
retE(answer);
}
//重複がある場合の処理
int answer = 1;
int max = T[0]; //とりあえず初期値は最初の提出で
//既出か管理するリスト
ArrayList<String> list = new ArrayList<String>();
list.add(S[0]);
//二番目から全探索
for(int i=1;i<N;i++){
//最大値更新候補か?
if(max<T[i]){
//リストに無い文字列か?
if(!(list.contains(S[i]))){
answer = i+1;
max = T[i];
list.add(S[i]);
}
}
//点数関係なく新しい文字列か?(else ifの方が良かった(?))
if(!(list.contains(S[i])))
list.add(S[i]);
}
//出力して終了
retE(answer);
}
//旧テンプレ
public static void retE(int ret){System.out.println(ret);System.exit(0);}
public static String read(){return sc.next();}
public static int readI(){return sc.nextInt();}
}
ArrayListを使ってるので少々遅いですが、まぁ許容範囲内でしょう。多分…。
D - At Most 3 (Contestant ver.)
問題文はこちら
コンテスト中は二進数で網羅するのか…?とかフィボナッチ数列でいくのか…?とか考えてしまいましたが、普通に1~99、100~9900、10000~990000を出力すれば終わりでしたね…。言われてみれば「あぁ…確かに…」って感じだったんですが、コンテスト中には思いつかないよ…。
class Main{
public static void main(String[] args){
//どうせこれでしかパッケージ下のクラスは使わないのでimportはしていない
java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
//おもりの数(99×3)
pw.println(297);
for(int i=0;i<3;i++){
for(int j=1;j<100;j++){
//1、100、10000*jを順に出力
pw.print(j*(int)Math.pow(10,i*2));
//区切り用の半角空白
pw.print(" ");
}
}
//改行してフラッシュ
pw.println();
pw.flush();
}
}
未だに若干悔しいですが、解き方を知れたので良しとしますか…。
総評
A、B:まんま実装するだけ。
C:重複管理が若干難しかった。
D:完全ひらめき問題。鬼畜。
って感じでした。
E問題は解けそうではあるんですが、まだ理解に時間がかかりそう…。