はじめに
今回はDまでコンテスト中に提出したものです(久々の4完。嬉しい)。
では見ていきましょう。
A - "atcoder".substr()
問題文はこちら
そのままです。
Javaではsubstringに相当しますね(第一引数は開始位置、第二引数は終了位置の一個後ろ)。
なお、文字列の一番最初の文字の添え字は1ではなく0なので第一引数はLではなくL-1であることに注意してください(Lは1文字目を1としているので1ズレている)。
class Main{
static Library System = new Library(java.lang.System.in,java.lang.System.out);
public static void main(String[] args)throws IOException{
//文字列を準備
String str = "atcoder";
//L、Rの受け取り
int L = System.in.nextInt();
int R = System.in.nextInt();
//L番目からR番目までを切り出して出力
System.out.println(str.substring(L-1,R));
System.out.close();
}
}
特に問題はないですね。
B - Nice Grid
問題文はこちら
問題文を見て「式でどうこうできそうだな」とは思ったのですが、何も思いつかなかったのでそのままグリッドを二次元配列に落とし込んで実装しました。
この解答では黒を1
、白を0
としています。
class Main{
static Library System = new Library(java.lang.System.in,java.lang.System.out);
public static void main(String[] args)throws IOException{
//R、Cの受け取り
int R = System.in.nextInt();
int C = System.in.nextInt();
//グリッドをそのまま二次元配列に
int[][] map = {
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,0,1},
{1,0,1,0,0,0,0,0,0,0,0,0,1,0,1},
{1,0,1,0,1,1,1,1,1,1,1,0,1,0,1},
{1,0,1,0,1,0,0,0,0,0,1,0,1,0,1},
{1,0,1,0,1,0,1,1,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,1,1,0,1,0,1,0,1},
{1,0,1,0,1,0,0,0,0,0,1,0,1,0,1},
{1,0,1,0,1,1,1,1,1,1,1,0,1,0,1},
{1,0,1,0,0,0,0,0,0,0,0,0,1,0,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
//1ならblack、0ならwhiteを出力
System.out.println(map[R-1][C-1]==1?"black":"white");
System.out.close();
}
}
式での実装はleaf1415さんの解説にありますので省略します。式見れば確かに・・・って感じなんですがね・・・気付かなかったです。
C - Matrix Reducing
問題文はこちら
bit全探索で実装しました(bit全探索に関してはこちらのサイトが詳しいと思います)。
実際に行・列を削除した行列を準備しサイズが違うならその時点で次の場合へ、サイズが一緒なら全部見て正誤判定をする、という感じです。
本当はわざわざ新しく行列を準備しなくてもAの見たい要素を参照すれば良い話なんですが、何故か実装が上手くいかなくてこのような実装になってしまいました。
class Main{
static Library System = new Library(java.lang.System.in,java.lang.System.out);
public static void main(String[] args)throws IOException{
//H1、W1、Aの受け取り
int H1 = System.in.nextInt();
int W1 = System.in.nextInt();
int[][] A = new int[H1][W1];
for(int i=0;i<H1;i++)A[i] = System.in.nextInt(W1);
//H2、W2、Bの受け取り
int H2 = System.in.nextInt();
int W2 = System.in.nextInt();
int[][] B = new int[H2][W2];
for(int i=0;i<H2;i++)B[i] = System.in.nextInt(W2);
//二重forによるbit全探索
for(int i=0;i<(1<<H1);i++){
Search:for(int j=0;j<(1<<W1);j++){
//切り出し用
ArrayList<ArrayList<Integer>> matrix = new ArrayList<ArrayList<Integer>>();
//i、jを元に行列を構築
for(int s=0;s<H1;s++){
if((i&(1<<s))==(1<<s))continue; //bitが立ってるならスルー
matrix.add(new ArrayList<Integer>());
for(int t=0;t<W1;t++){
if((j&(1<<t))==(1<<t))continue; //bitが立ってるならスルー
matrix.get(matrix.size()-1).add(A[s][t]);
}
}
//サイズが違うならスルー
if(H2!=matrix.size()||W2!=matrix.get(0).size())continue;
//全要素を調べる
for(int s=0;s<H2;s++){
for(int t=0;t<W2;t++){
if(matrix.get(s).get(t)!=B[s][t])continue Search; //違うなら次へ
}
}
//全部合ってたならYesを出力して終了
System.out.println("Yes");
System.out.close();
java.lang.System.exit(0);
}
}
//forを抜け出した=1回も一致しなかったのでNoを出力
System.out.println("No");
System.out.close();
}
}
ちょっと汚いですね・・・。コンテスト中とはいえ、もうちょっと考えて実装しないとです・・・。
D - "redocta".swap(i,i+1)
問題文はこちら
深いことは考えず、選択ソートみたいなことをしました。
"atcoder"を上手く順序付けても良いんですが、普通にaから順に並べていくときに必要なswapの回数を数えました。
class Main{
static Library System = new Library(java.lang.System.in,java.lang.System.out);
public static void main(String[] args)throws IOException{
//Sをchar型配列として受け取り
char[] S = System.in.next().toCharArray();
//答え用変数
int count = 0;
//aを探す
for(int i=0;i<7;i++){
//見つけたら移動回数をcountに加算して移動
if(S[i]=='a'){
count += i;
for(int j=i;j>0;j--){
char temp = S[j];
S[j] = S[j-1];
S[j-1] = temp;
}
break;
}
}
//t~dも同様に---------------------
for(int i=1;i<7;i++){
if(S[i]=='t'){
count += i-1;
for(int j=i;j>1;j--){
char temp = S[j];
S[j] = S[j-1];
S[j-1] = temp;
}
break;
}
}
for(int i=2;i<7;i++){
if(S[i]=='c'){
count += i-2;
for(int j=i;j>2;j--){
char temp = S[j];
S[j] = S[j-1];
S[j-1] = temp;
}
break;
}
}
for(int i=3;i<7;i++){
if(S[i]=='o'){
count += i-3;
for(int j=i;j>3;j--){
char temp = S[j];
S[j] = S[j-1];
S[j-1] = temp;
}
break;
}
}
for(int i=4;i<7;i++){
if(S[i]=='d'){
count += i-4;
for(int j=i;j>4;j--){
char temp = S[j];
S[j] = S[j-1];
S[j-1] = temp;
}
break;
}
}
//---------------------------------
//最後、入れ替える必要があるなら+1
if(S[5]=='r')count++;
//答えの出力
System.out.println(count);
System.out.close();
}
}
a~dを別々に書くんじゃなくてさらにforでネストした方がよかったかも?けどそんなことするなら転倒数の考えを用いるとか文字に応じた順序付けを行なってバブルソートするだとかした方が良い気もする。
感想
A:atcoder受け取ると思ってたからちょっとびっくり。
B:式を立てようとしたけど上手くいかないから配列で・・・。
C:実装にすんごい時間かかってしまった。慣れてないですね。
D:B、Cより簡単なのでは・・・?
って感じでした。
Dまでは難易度がそんな高くなかったように思うので、速解きを求められるコンテストだったように感じています。