はじめに
このコンテストは私が初めてrated参加したときのコンテストです。思い出深いです。
昔書いたコードなので今の自分が書くなら~っていうコードも一緒に書きます。
では、実際にコードを解説していきます。
A - Digit Machine
問題文はこちら
初期値0として実際に試行してみれば答えが出ます。いわゆるやるだけ。
import java.io.*;
//値取得用クラス
class subMain{
public static int[] parsingInt(String someInt){
//取得した文字列を空白区切りで格納
String[] str = someInt.split(" ");
int[] Intel = new int[str.length];
//一つずつparseIntして格納
for(int i=0;i<str.length;i++){
Intel[i] = Integer.parseInt(str[i]);
}
return Intel;
}
}
class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//値の取得
int[] num = subMain.parsingInt(br.readLine());
//初期値の設定
int answer = 0;
int number = 0;
//三回分試行
for(int i=0;i<3;i++){
answer = num[number];
number = answer;
}
//答えの出力
System.out.println(answer);
}
}
これはまぁこのままでも良いですが、書き直すとしたらこんな感じでしょうか。
import java.io.*;
class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//空白区切りで値の取得(String型のまま)
String[] num = br.readLine().split(" ");
//初期値設定
int answer = 0;
int number = 0;
//三回分試行
for(int i=0;i<3;i++){
answer = Integer.parseInt(num[number]);
number = answer;
}
System.out.println(answer);
}
}
parseIntの分ちょっと遅くなるかもしれませんが、わざわざ数列を全てint型に変換する必要もないので多分この方が速いでしょう。
B - Pasta
問題文はこちら
普通に順に探していって全部探せたらYes
、見つからなかったケースがあればNo
と出力すれば良いですね。
import java.io.*;
//値取得用クラス
class subMain{
public static int[] parsingInt(String someInt){
String[] str = someInt.split(" ");
int[] Intel = new int[str.length];
for(int i=0;i<str.length;i++){
Intel[i] = Integer.parseInt(str[i]);
}
return Intel;
}
}
class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//値の取得
int[] NM = subMain.parsingInt(br.readLine());
int[] Anum = subMain.parsingInt(br.readLine());
int[] Bnum = subMain.parsingInt(br.readLine());
//Bを順番に見ていく
for(int i=0;i<Bnum.length;i++){
//食べられるかどうかのboolean型変数
boolean CanEat = false;
//Aを全部見ていってちょうどの長さのものを探す
for(int j=0;j<Anum.length;j++){
//見つけたらtrueにして模索終了
if(Anum[j]==Bnum[i]){
Anum[j] = 0;
CanEat = true;
break;
}
}
//見つからなかったら終了
if(!CanEat){
System.out.println("No");
System.exit(0);
}
}
//全通り見つかったらYesを出力
System.out.println("Yes");
}
}
方針は一緒ですが、やっぱりsubMainクラスは避けたいなって感じているので書き直すならこんな感じですね。
ちなみに、subMainクラスを使うとNもMもほぼ意味を成さないんですよね(一列取得して空白を頼りに分割してるので)。
import java.io.*;
class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//最初の値はただのデコイなので破棄
br.readLine();
//A、BをString型のまま取得(空白区切り)
String[] Anum = br.readLine().split(" ");
String[] Bnum = br.readLine().split(" ");
//以下はB.javaと一緒
for(int i=0;i<Bnum.length;i++){
boolean CanEat = false;
for(int j=0;j<Anum.length;j++){
if(Anum[j].equals(Bnum[i])){
Anum[j] = "";
CanEat = true;
break;
}
}
if(!CanEat){
System.out.println("No");
System.exit(0);
}
}
System.out.println("Yes");
}
}
NとMは不要なのでreadLine()で捨て去りましょう。あと、AもBもわざわざ数字で受け取る必要がなさそうなのでString型のまま処理しています。
C - Connect 6
問題文はこちら
素直に6個できるかどうか全探索すれば良さそうです。2カ所は塗れるので、6個見て4カ所以上黒ならYes
を出力してやりましょう。
import java.io.*;
//値取得用クラス
class subMain{
public static String[] parStr(String someStr){
//受け取った文字列を一文字ずつ区切って配列に格納
String[] str = someStr.split("");
return str;
}
}
class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//値取得
int N = Integer.parseInt(br.readLine());
String[][] BW = new String[N][N];
for(int i=0;i<N;i++){
BW[i] = subMain.parStr(br.readLine());
}
//横の検証
for(int i=0;i<N;i++){
//一番端っこを検証できるのはj=N-6の時なのでそこまで探索する
for(int j=0;j<(N-5);j++){
int sharp = 0;
//#がいくつあるかカウント
for(int k=j;k<(j+6);k++){
if(BW[i][k].equals("#"))
sharp++;
}
//6ついけそうなら終了
if(sharp>=4){
System.out.println("Yes");
System.exit(0);
}
}
}
//縦の検証
for(int i=0;i<(N-5);i++){ //縦方向だとi<N-5までだということに注意
for(int j=0;j<N;j++){
int sharp = 0;
//#いくつありそう?
for(int k=i;k<(i+6);k++){
if(BW[k][j].equals("#"))
sharp++;
}
//塗れそうなら終了
if(sharp>=4){
System.out.println("Yes");
System.exit(0);
}
}
}
//右下方向の検証(斜めになるとi,j<N-5になることに注意)
for(int i=0;i<(N-5);i++){
for(int j=0;j<(N-5);j++){
int sharp = 0;
//#はいくつ?
for(int k=0;k<6;k++){
if(BW[i+k][j+k].equals("#"))
sharp++;
}
//いけそうなら終了
if(sharp>=4){
System.out.println("Yes");
System.exit(0);
}
}
}
//右上方向の検証(なんとなく右上から左下に模索するように記述したのでi=5からです)
for(int i=5;i<N;i++){
for(int j=0;j<(N-5);j++){
int sharp = 0;
//#探し
for(int k=0;k<6;k++){
if(BW[i-k][j+k].equals("#"))
sharp++;
}
//いけそうならYesを
if(sharp>=4){
System.out.println("Yes");
System.exit(0);
}
}
}
//検出できなかった場合はNo
System.out.println("No");
}
}
これは正直これ以上変更を加える必要もないんですが、subMainクラスを省いて書き換えてみます。
import java.io.*;
class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//値取得
int N = Integer.parseInt(br.readLine());
String[][] BW = new String[N][N];
for(int i=0;i<N;i++){
BW[i] = br.readLine().split("");
}
//以下C.javaと同じ
}
もっと良い書き方があると思いますが全部分けた方が何やってるかわかりやすいんでこのままで良いと思います。
総評
A:実装するのみ
B、C:真面目に全探索するのみ
って感じでした。コンテスト終わってからまだDとか解いてないので解けたらそのうち載せようかなって思います。