はてなブログでソースコードを綺麗に表示する方法
こんにちは。
これまでいくつかのプログラムを載せていましたが、スペースが全て省略されてしまい、とても見れたものではありませんでした。
自分なりに調べて方法を確立したので、メモとして残しておきます。
①設定方法
ダッシュボード→設定→編集モード→はてな記法モード
初期設定では見たままモードになっていると思います。
②書き方
「>||」と「||<」
で挟むだけです。
プログラム毎に色付けしたいときは、
「>|言語名|」と「||<」
で挟みます。
例えばjavaの場合だと、
>|java| public class Main { public static void main(String[] args){ System.out.println("Helloworld!"); } } ||<
と書くことで
public class Main { public static void main(String[] args){ System.out.println("Helloworld!"); } }
このように表示することができます。
以上メモでした
Javaの練習にABC#002を解いてみました
どうも、6日ぶりの更新になります。
最近は英語の方に注力してしまっていて、なかなかプログラミングができませんでした。
しかし、3月1日にAtcoderのレギュラーコンテストが開催されるようなので、それに向けて励んでいこうと思います。
今日はABC002を解いてみました。ABCはビギナーコンテストというだけあって、問題の幅が広く、私のような初心者の練習には丁度いい!
開催側で解説も用意されているので、非常に助かっております。
競技プログラミング初心者の方にはおすすめです。
まずは問題のリンク
Tasks - AtCoder Beginner Contest #002 | AtCoder
今回も1~2番はかなり簡単な問題、3番は少し考えさせる問題、そして4番はなかなか解き応えのある問題というような構成でした。
ということで今回は4番の問題だけ取り扱おうと思います。
D: 派閥 - AtCoder Beginner Contest #002 | AtCoder
これは全探索を使って解きました。(解説を見るまでは、意味の分からないアルゴリズムで撃沈していたのは秘密)
Nが最大12なので、全ての派閥の組み合わせを探索したとしても最大でも2^12=4096通りです。この程度の数なら全探索で余裕です。(解説の受け売りです)
AtCoder Beginner Contest 002 解説
全探索のパターンの調べ方としては、上の解説の14ページの方法を使いました。
それに伴い、探索方法はビット演算を用いたものになっています。
ビット演算をプログラムで行ったのは初めてだったのでなかなか苦戦しました。
今回知らなかったことをメモとしておいておきます。
シフト演算記号
1 >> N ←1をNビットだけ右シフト
1 << N ←1をNビットだけ左シフト
& ← AND演算子
ではソースを置いておきます。
import java.util.Scanner;
public class Main4 {
public static void main(String args){
Scanner stdin = new Scanner(System.in);
int N = stdin.nextInt();
int M = stdin.nextInt();
boolean[] lis = new boolean[N][N];
for(int i=0; i<M; i++){
int a = stdin.nextInt()-1;
int b = stdin.nextInt()-1;
lis[a][b]=true;
}
int size = 1 << N;
int max=1;
int bitnum=1;
if(M==0){
System.out.println(max);
}else{
LOOP:
for(int bit=1; bit<size; bit++){
bitnum=0;
for(int a=0; a<N-1; a++){
if((bit & 1 << a) == 0){
continue;
}
for(int b=a+1; b<N; b++){
if((bit & 1 << b)== 0){
continue;
}else if(!lis[a][b]){
continue LOOP;
}
}
}
for(int i=0; i<N; i++){
if((bit & 1 << i)!=0){bitnum++;}
}
if(max<bitnum)max=bitnum;
}
System.out.println(max);
}
stdin.close();
}
}
最初は全く分からない問題でも、解説を見たり、他の参加者の方のソースを拝見させて頂いたりすることで、アルゴリズムや考え方が身についてくると思います。
プログラミングの世界は、上には上がいる(いすぎる)のでやる気が削がれてしまうことは有るかもしれませんが地道に頑張っていこうと思います。
では今日はこれくらいで。
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の解説
AtCoder Beginner Contest#004に参加しました。
僕にとっての初めてのプログラミングコンテストでした。
「beginner contestというくらいだから、自分でも解けるだろう~」と楽観的な気持ちで臨んだのですが、見事に打ち砕かれました。
4問中完全にできたのは最初の3問のみでした。最後の問題は途中点だけ何とか貰う形に、、
とりあえず問題のリンクと僕の書いたコードを置いていこうと思います。
言語はCで書きました。競技プログラミングでCを使う人は少ないのかな?しかし僕はCとjavaしか書ける言語がない(しかもjavaはほとんど忘れている)、というにわかプログラミング学習者のテンプレのような男なのでCで書きました。
まず1問目
A: 流行 - AtCoder Beginner Contest #004 | AtCoder
これは多分誰でもできるんじゃないかな?コードは省きます。数値を一つ入力してそれを2倍して返してあげるだけです。
次に2問目
B: 回転 - AtCoder Beginner Contest #004 | AtCoder
これは空白挟んだ4×4の文字列を上下反転させて出力させるという問題です。以外にこの問題に苦戦してしまった私がいます。scanf分かりづらいんじゃ
コードはこんな感じになりました。scanfが未だによく分かっていない私。
最初はscanfの中に改行コードを入れていなかったのですが、それだと上手くいかなかったため改行を入れてみたところACが出たので結果オーライということで。
putやらgetやらで書いた方が簡単なのかな。
#include <stdio.h>
int main(void){
char s[4][4];
int i,j;
for(i=0; i<4; i++){
scanf("%c %c %c %c\n", &s[i][0], &s[i][1], &s[i][2], &s[i][3]);
}
for(i=3; i>=0; i--){
printf("%c %c %c %c\n", s[i][3], s[i][2], s[i][1], s[i][0]);
}
return 0;
}
次は3問目
C: 入れ替え - AtCoder Beginner Contest #004 | AtCoder
ここから少しだけ難しくなります。というよりこれは問題の意図に気が付けるか、というところですね。
あることに気が付かないと処理が間に合わずTA(タイムアップ)になってしまいます。
私はもれなく引っかかりました。実際少し考えれば分かることなのですが、本番だとテンパッてしまいますね。最終的に提出してACを貰ったコードを下に貼ります。にしても汚いコードだな。。
#include <stdio.h>
int main(void){
int num[6]={1,2,3,4,5,6};
int n, i, j, temp, wa, mod;
scanf("%d", &n);
n = n%30;
wa = n/5;
mod= n%5;
for(i=0; i<wa; i++){
for(j=0; j<5; j++){
temp = num[j];
num[j] = num[j+1];
num[j+1] = temp;
}
}
for(i=0; i<mod; i++){
temp = num[i];
num[i] = num[i+1];
num[i+1] = temp;
}
for(i=0; i<6; i++){
printf("%d", num[i]);
}
printf("\n");
return 0;
}
4問目
D: マーブル - AtCoder Beginner Contest #004 | AtCoder
僕はこいつにやられました。初心者には難しすぎるよ。。。ちなみに未だに解けていません。解き次第、ここに報告する形にします。
全探索を使うのかな?もう少し慣れてから挑戦します。
と、僕の初めてのプログラミングコンテストはこんな感じで終わりました。順位は137位でした。まぁこんなもんだよな。。
結果はあまり良いものではありませんでしたが、とても楽しかった!!
これを機にプログラミングともう少し向き合おうと思えたので良かったと思います。(仮にも一応情報系なのでorz)
では今日はこれくらいで。