今日も独りで立ち話

ポンコツ博士課程の院生が思ったことをそのまま書くブログ

MENU

知識0からプログラミングを始めた(AtCoder挑戦1週目)

研究もうまくいかず、就活もうまくいかず、にっちもさっちもいかなくなったので
手に職をつける選択肢を広げるために、プログラミングの勉強を始めることにしました

 

博士卒(まだできるかわからんけど)が就活失敗したら、エンジニアにならざるを得ないので、それなら今のうちにやっとくかみたいな感じ 

 

とはいえ、自分のプログラミング経験は大学の講義でCを触ってすぐに挫折したくらいの実力しかないので、完全に初心者です

 

まじでなんもわからんので
C++入門 AtCoder Programming Guide for beginners (APG4b)
を毎日少しずつ解きながら勉強していくつもり

 

ここにちょっとずつ追記していく

 

1日目(練習問題も含めて1.00~1.05まで終了)

「using namespace std;」についての理解
名前空間は"関数的なもの"が定義できて、STLとかはstdって名前のところに入ってる
本来、この名前空間から"もの"を引っ張り出してくるには、「名前空間::」って記述をする必要がある

そこを「using namespace 名前空間;」と書くと、これ以降はいちいち呼び出してこなくてもいつでも使える状態にできる
だから初心者段階では最初にこれを書いておくことで、便利道具を呼び出せない、みたいなミスを避けられる

>> 規模が大きくなると名前の衝突を避けることが大変になる
の意味がよくわからんけど、下位で定義した名前空間とstdで名前被りを避けるのが面倒になるから、いちばん大枠でこれを宣言するのはあんまりよくない

みたいな認識であってるのかな
うーん、わからん

 

#include <bits/stdc++.h>について
ドラえもんの4次元ポケットを最初に持ってくるみたいな認識でいいんかな
とりあえず持ってきておけば間違いはない、という感じで

業務におけるプログラミングでは推奨されないことがある、という記述があって調べたけどよくわからんかった

 

1.04まではあんまりプログラミングっぽくはなくて、どっちかというと数学の知識だけだったから特に問題はなし

 

型のくだりくらいかな?

int が整数でdoubleが小数なのに注意するのと、doubleをintに代入すると制約のきついintにそろうことは覚えておく

 

cinは一体なんのために存在しているのかよくわからんけど、後々どっかで入力した値を拾ってくるみたいなのが重要になってくるんかな?

今は直接入力してたらだめなんか・・・?みたいなこと考えてるけど、「一般性」みたいな感じで拡張するには、こうするほうが丸いんだろうな(と納得させている)

 

入力に条件がついてて、その条件に合わない入力を弾かないといけないと思うんだけど

今のところ、それに該当するプログラムは書けていないのが現状なんだよね

書き方がわからないし、書いてもないんだけど、なぜか通ってるからまあいいか、みたいに今は気にしないようにしてる

 

1.05について

A - Round Up the Mean を解いててなんでこれで間違いかよくわからん状況に遭遇した

#include <bits/stdc++.h>
using namespace std;

int main() {
int a, b;
cin >> a >> b;
double x;
x= ((a+b)/2)+0.5;
int y = x;
cout << y << endl;

}

 これで不正解で

#include <bits/stdc++.h>
using namespace std;

int main() {
int a, b;
cin >> a >> b;
double x;
x= ((a+b+1)/2);
int y = x;
cout << y << endl;

}

 これで正解なのはなんでなんだ…?

計算自体はdoubleで計算した後、小数を良い感じにいじってintで落としてるだけだし

やってることは変わらんはずなんやけど…

 

2日目(1.06)

結構、愚直な条件で無駄に長く記述しがちだから、他の人の条件は参考になった

!(条件式) 
条件式1 && 条件式2 
条件式1 || 条件式2 

の3つの論理演算子を使うのが苦手なんよなあ

 

あとは3つの数字が等しいって条件を書く場合は

 a == b == c

じゃダメで

 a == b && b == c

って書かないといけない気付きを得た

 

3日目(1.07)

真偽判断の話

bool a = true;

ってあえて入れ込む理由はよくわからん

 

4日目(1.08)

スコープの話

宣言したところでしか変数は作用しないのは言われてみれば当たり前だけど、大事そう

 

5日目(1.09~1.10)

6日目(1.11 途中)

ループの話

このへんから難しくなってきた

説明はわかるんだけど、問題になると格段に難しくなる感じ

EX11.電卓をつくろう2は不格好だけど、なんとかクリアできたんだけど

ABC問題のほうで大苦戦した

今日はB - Hina Arareで1時間くらい足止めされてしまった

if, else, else ifの違いがあやふやだったことが原因だった

特にelse ifのif の条件が偽かつelse ifの条件が真のときに{}の中の処理をするということはどういうことなのか実感した

 

#include <bits/stdc++.h> 
using namespace std;
int main() {
int A = 0;
int B = 0;
int C = 0;
int N;
cin >> N;
for(int i = 0; i < N; i++){
string S;
cin >> S;
if(A >= 1 && B >= 1 && C >= 1){
if(S == "Y"){
cout << "Four" << endl;
break;
}
else if(i >= N -1 && S !="Y"){
cout << "Three" << endl;
break;
}
}
else if(S == "W"){
A++;
}
else if( S == "P"){
B++;
}
else if( S == "G"){
C++;
}
}
}
}

 これがB - Hina Arareで書いたコード

これに至るまでにいくつかエラーが出たときもあったんだけど、その理由がイマイチわかってないのはよくないかなあとは思ってる

多分、ifの処理の過程なんだとは思うけど

 

7日目(1.11問題)

B - Harshad Numberで感心したコードを見つけた

自分は一番大きい桁から取得していく方針だったので、その桁の数字を取得し元の数から引いていく(148なら,148/100=1をしたあと、(148-1*100)/10=4、(148-1*100-4*10)/1=8)のように計算していく方針を立てた

桁数で割れば小数点以下はint型なら無視できるので、地道に拾っていけばなんとかなると思った

実際は繰り返し処理を記述できなかったため、桁数が8桁と物理的に書けるオーダーだったのもあって

 

 #include <bits/stdc++.h>
using namespace std;

int main() {
int N;
cin >> N;
int a, b, c, d, e, f, g, h, i = 0;
a = N / 100000000;
b = (N - a * 100000000) / 10000000;
c = (N - a * 100000000 - b * 10000000) / 1000000;
d = (N - a * 100000000 - b * 10000000 - c*1000000) / 100000;
e = (N - a * 100000000 - b * 10000000 - c*1000000- d*100000) / 10000;
f = (N - a * 100000000 - b * 10000000 - c*1000000- d*100000 - e* 10000) / 1000;
g = (N - a * 100000000 - b * 10000000 - c*1000000- d*100000 - e* 10000 - f* 1000) / 100;
h = (N - a * 100000000 - b * 10000000 - c*1000000- d*100000 - e* 10000 - f* 1000 - g*100) / 10;
i = (N - a * 100000000 - b * 10000000 - c*1000000- d*100000 - e* 10000 - f* 1000 - g*100 - h*10) / 1;

int sum = a + b + c + d + e + f + g + h + i;

if(N % sum ==0){
cout << "Yes"<< endl;
}
else{
cout << "No" << endl;
}
}

 こんな感じのパワープレイで押し切ったのだけど、他の人の回答ですばらしいものを見つけた

 

#include<iostream>
using namespace std;
int main(){
int N, fN = 0, n;
cin >> N;
n = N;
while(n > 0){
fN += n % 10;
n /= 10; }

if(N % fN) cout << "No" << endl;
else cout << "Yes" << endl;
}

10で割った余りで下から拾っていく発想は出てこなかったので見習いたい

こういう風にできるだけシンプルでわかりやすいコードをかけるようになりたい