底辺大学生の奮闘プログラミング+α

プログラミング初心者が毎日書いたコードを載せたりします。競技プログラミングにも随時参加します。

javaの練習のためにABC001を解いてみました。

Javaはほとんど忘れている状態だったので、こりゃいかんと思い、かなーり久々にeclipseを起動(まともに使ったことも無い)

そして、ABC004に参加したこともあり、今回はABC001の問題を解いてみました。

全体的にこちらの方が簡単ではあったかな?4問目はかなり時間がかかってしまいましたが。。。

 

1問目

A: 積雪深差 - AtCoder Beginner Contest #001 | AtCoder

これはただ引き算するだけなので割愛

 

2問目

B: 視程の通報 - AtCoder Beginner Contest #001 | AtCoder

これも作業ゲーですね。特筆することも無いため割愛

 

3問目

C: 風力観測 - AtCoder Beginner Contest #001 | AtCoder

これも作業ゲーで書こうと思えば書けるのですが、それではつまらないため、計算で解きました。(風力の方は全て列挙したので、全て計算で解いたわけではないです面目ない)

これを書いたときに知らなかったことをメモとして残しておきます。

・四捨五入のやり方

double kazu;  //四捨五入したい数

BigDecimal gonyu = new BigDecimal(String.valueOf(kazu));

double kazu2 = gonyu.setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();

 

setScale(数字、~)の数字を変えることで四捨五入する桁を変えることができます。0で少数第一位、1で少数第二位、と続いていきます。

今回の場合は1なので少数第二位で四捨五入しています。

 

以下コード

import java.util.Scanner;

import java.math.BigDecimal;

 

public class Main3 {

 

 

public static void main(String args){

Scanner stdin = new Scanner(System.in);

int deg = stdin.nextInt();

int dis = stdin.nextInt();

 

String str = {

"N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW","C"

};

 

int a = (deg*10-1125)/2250+1;

if(deg*10 < 1125 || deg*10>34875){a = 0;}

 

double disans = (double)dis/60;

BigDecimal bi = new BigDecimal(String.valueOf(disans));

double d2 = bi.setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();

 

int kaze=0; 

if(d2<=0.2)kaze=0;

else if(d2<=1.5)kaze=1;

else if(d2<=3.3)kaze=2;

else if(d2<=5.4)kaze=3;

else if(d2<=7.9)kaze=4;

else if(d2<=10.7)kaze=5;

else if(d2<=13.8)kaze=6;

else if(d2<=17.1)kaze=7;

else if(d2<=20.7)kaze=8;

else if(d2<=24.4)kaze=9;

else if(d2<=28.4)kaze=10;

else if(d2<=32.6)kaze=11;

else if(d2>=32.7)kaze=12;

 

if(kaze == 0)a=16;

 

System.out.println(str[a] +" "+ kaze);

}

}

 

問題4

D: 感雨時刻の整理 - AtCoder Beginner Contest #001 | AtCoder

当たり前ですが、この問題が一番難しかったです。知らないことを使いまくりました。

多分これを書くだけで3時間くらいかかったんじゃなかろうか。。本当に初心者ですorz

多分かなり効率の悪いやり方をしてしまったのでは無かろうか。

 

僕のやり方としては

①出力を一行ずつ配列に格納し、それをソート。←今回の場合は早い時間から処理すると手間が省けるので最初にソートしてしまいます。

②その文字列のまま数値として処理できないので、配列から2つの数字を得る。そしてその数値をまるめる。

③被ってる時間を合体させて出力。

といったところです。(時間を正確に丸めることができておらずにWA(ロングアンサー)を出しまくったのは秘密。)

ソース貼っつけます。

 

import java.util.Arrays;

import java.util.Scanner;

 

public class Main4 {

public static int marume(int time, int flag){

int marume = time;

if(marume%5==0){return marume;}

else{

while(marume%5!=0){

if(flag==0){marume=marume-1;}

else{marume=marume+1;}

}

if(flag == 1){

String m_str = Integer.toString(marume);

if(marume>=1000){m_str = m_str.substring(2);}

else if(marume<1000 && marume>=100){m_str = m_str.substring(1);}

if(m_str.equals("60")){

marume = marume+40;

}

}

return marume;

}

}

 

public static void main(String args){

Scanner stdin = new Scanner(System.in);

int N = stdin.nextInt();

 

String time = new String[N];

for(int i=0; i<N; i++){

time[i] = stdin.next();

}

Arrays.sort(time);

int start = new int[N];

int end = new int[N];

for(int i=0; i<N; i++){

String time2 = time[i].split("-");

start[i] = Integer.parseInt(time2[0]);

start[i] = marume(start[i],0);

end[i] = Integer.parseInt(time2[1]);

end[i] = marume(end[i],1);

}

int flag = new int[N];

Arrays.fill(flag, 0);

 

for(int i=0; i<N; i++){

if(flag[i]==0){

for(int j=i+1; j<N; j++){

if(end[i]>=start[j]){

//System.out.println("tes1");

if(end[i]<=end[j]){

end[i]=end[j];

}

flag[j]=1;

if(j==N-1)System.out.println(String.format("%04d",start[i])+"-"+String.format("%04d",end[i]));

}else{

//System.out.println("tes2");

System.out.println(String.format("%04d",start[i])+"-"+String.format("%04d",end[i]));

break;

}

}

if(i==N-1){

System.out.println(String.format("%04d",start[i])+"-"+String.format("%04d",end[i]));

}

}

}

}

}

 

かなり長いコードになってしまいました。

ここでも今回新たに知ったことをメモとして残しておきます。

 

・配列のソート

import java.util.Arrays;をインポートして

 Arrays.sort(配列名);

 

・配列をまとめて初期化

Arrays.fill(配列名, 初期値)

 

・文字列の特定の場所から始まる新たな文字列を生成

String str = "Hello";

str = str.substring(2);

括弧の数字でどこから始まるか決めます。

この場合、strは"llo"となります。2が0だった場合、"ello"となります。

 

・2つの文字列が等しいか確認する

str.equals("60")

この場合strは"60"と等しければtrueを等しくなければfalseを返します。

 

 

・文字列を分解

String str = "Hello world""

String[] str2 = str.split(" ");

この場合だと、空白で分割されるので、str2[0]="Hello", str2[1]="world"となります。

 

多分これくらいかな

Stringにオプションが多くて驚きました。こりゃ便利ですわ。

ABC001の解説が挙がっていたので、それを見たところ、何と最後の問題はもっと簡単に出来た様子。

悔しいのでもう一度書いてみます。

ではでは。

↓ABC001の解説

ABC001 解説