AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その6)
第7問(ABC 085 B - Kagami Mochi)の類題を解いていきます。
#include <iostream> #include <algorithm> #include <string> #include <set> using namespace std; int main() { string str; int length,i; set<char> alphabets; cin >> str; length = str.length(); for(i = 0; i<length; i++){ alphabets.insert(str[i]); } set<char>::iterator it; for(i = 'a';i <= 'z'; i++) { it = alphabets.find(i); if(it == alphabets.end()){ cout << (char)i << endl; return 0; } } cout << "None" << endl; return 0; }
- 各都市(数値で表される)を配列のキーとして用意しておき、2行目以降、その数値が出るたびにキーの値をインクリメントさせる
- 今思えばmap使わなくても普通の配列でできたかなと思うけど、、、まあいいか。
#include <iostream> #include <algorithm> #include <string> #include <map> using namespace std; int main() { int number_of_cities,number_of_roads,i,j,k; map<int,int> road_to_city; cin >> number_of_cities >> number_of_roads; for(i = 0 ; i< number_of_cities; i++) { road_to_city[i] = 0; } for(i = 0; i < number_of_roads;i++) { cin >> j >> k; road_to_city[j-1]++; road_to_city[k-1]++; } for(i = 0; i<number_of_cities;i++){ cout << road_to_city[i] << endl; } return 0; }
ABC 047 B - Snuke's Coloring 2 (ABC Edit)
- 一旦xとy座標を変数にした後、4象限(x軸の上側、下側、y軸の上側、下側)で隠される面積を割り出して、引き算する。
- 多分もっといい解法があるんだろうとは思うけど、今の実力ではこれがいっぱいいっぱいでした。
#include <iostream> #include <algorithm> #include <string> #include <map> #include <cmath> using namespace std; int main() { int x,y,i,j,k,l,number_of_coloring; int left_coloring_x = 0; int right_coloring_x = 0; int upper_coloring_y = 0; int lower_coloring_y = 0; cin >> x >> y >> number_of_coloring; for(i = 0; i < number_of_coloring;i++){ cin >> j >> k >> l; switch(l){ case 1: if(left_coloring_x < j){ left_coloring_x = j; } break; case 2: if(right_coloring_x < abs(x - j)){ right_coloring_x = abs(x - j); } break; case 3: if(lower_coloring_y < k){ lower_coloring_y = k; } break; case 4: if(upper_coloring_y < abs(y - k)){ upper_coloring_y = abs(y - k); } break; } } x = x - left_coloring_x - right_coloring_x; y = y - lower_coloring_y - upper_coloring_y; if(x <= 0 || y <= 0) { cout << 0 << endl; } else { cout << x * y << endl; } return 0; }
ABC 091 B Two Colors Card Game
- mapを用意
- 青いカードのときは文字列を見るたびににその文字をキーとして数値をインクリメント
- 赤いカードのときはその逆でその文字キーで数値をデクリメント
- あとはmapを上からキーを走査して、もっとも大きい数値を出力する
#include <iostream> #include <algorithm> #include <string> #include <map> #include <cmath> using namespace std; int main() { int i,number_of_bluecard,number_of_redcard; map<string,int> strs; string str; int max_yen = 0; cin >> number_of_bluecard; for(i = 0; i< number_of_bluecard; i++){ cin >> str; if(strs.find(str) == strs.end()){ strs[str] = 1; } else { strs[str]++; } } cin >> number_of_redcard; for(i = 0;i<number_of_redcard; i++){ cin >> str; if(strs.find(str) != strs.end() && strs[str] != 0 ){ strs[str]--; } } for(auto itr = strs.begin(); itr != strs.end(); itr++){ if(max_yen < itr->second) { max_yen = itr->second; } } cout << max_yen << endl; return 0; }
- 入力される数値をキーとして、各数値の出現回数をカウント
- 出現回数が多い順にキーをソート
- 規定されている数値の種類までカウントし、超えた場合は各キーに紐づく値を足し算していく
#include <iostream> #include <algorithm> #include <string> #include <map> #include <cmath> using namespace std; int main() { int i,ball,balls,num_ball_type; int ball_type[210000] = {0}; int counter = 0; int number_of_changed_type = 0; cin >> balls >> num_ball_type; for(i = 0; i < balls; i++){ cin >> ball; ball_type[ball]++; } sort(ball_type,ball_type+210000,greater<int>()); for(i = 0; i < 210000; i++){ if(ball_type[i] == 0){ break; } if(counter >= num_ball_type) { number_of_changed_type += ball_type[i]; } else { counter++; } } cout << number_of_changed_type << endl; return 0; }
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その5)
最近サボってた。 ABC 083 B - Some Sumsの類題を解く。
ABC 080 B - Harshad Number + 与えられた数値を10で割っていきながら各位の値を足し算していく。 + その後、足し算した値で割り切れるかどうかを判定。
#include <iostream> using namespace std; int main() { int N,i,sum; cin >> N; i = N; while(i > 0){ sum += i % 10; i /= 10; } if(N % sum == 0){ cout << "Yes" << endl; } else { cout << "No" << endl; } return 0; }
ABC 090 B - Palindromic Numbers
- 与えられた数値の範囲内でループを回す
- ループごとに各位の値を分解して配列にわたす
- 一の位と一万の位、ならびに十の位と千の位の値が同じかどうか判定する
#include <iostream> using namespace std; int main() { int i,j,k,first,last,digits[10]; int counter = 0; cin >> first >> last; for(i = first; i <= last; i++){ j = i; k = 0; while(j > 0) { digits[k] = j % 10; cout << digits[k] << endl; j /= 10; k++; } if(digits[0] == digits[4] && digits[1] == digits[3]){ counter++; } } cout << counter << endl; return 0; }
続いて第6問(ABC 088 B - Card Game for Two )の類題。
- とりあえずソートさせて終わり。
- もうちょっとだけ補足すると、数値を大きい順番に並べ替えて順番に足し算していきます。
#include <iostream> #include <algorithm> using namespace std; int main() { int i,N,rods; int rod[60]; int maxlength = 0; int length = 0; cin >> N >> rods; for(i = 0; i < N; i++){ cin >> rod[i]; } sort(rod,rod+N,greater<int>()); for(i = 0; i < rods;i++){ length += rod[i]; } if(maxlength <= length) { maxlength = length; } cout << maxlength << endl; return 0; }
ABC 064 B - Traveling AtCoDeer Problem
- 最初は問題文を読んで??となったのですが、要するに与えられた値から最小と最大の値を抜き出してその差をとることだとわかってからはそこまで苦労しなかった。
- ソートしたほうが早かったかも。
#include <iostream> #include <algorithm> using namespace std; int main() { int i,N,coodinates[1100]; int maxcoodinate = 0; int mincoodinate = 0; cin >> N; for(i = 0; i < N; i++) { cin >> coodinates[i]; } mincoodinate = coodinates[0]; maxcoodinate = coodinates[0]; for(i = 1; i < N; i++) { if(coodinates[i] <= mincoodinate) { mincoodinate = coodinates[i]; } if(coodinates[i] >= maxcoodinate) { maxcoodinate = coodinates[i]; } } cout << maxcoodinate - mincoodinate << endl; return 0; }
ABC 042 B - Iroha Loves Strings
- 文字列のソート処理
- ソートさせたあと、順番に文字列連結させてます。
#include <iostream> #include <algorithm> #include <string> using namespace std; int main() { int i,N,L; cin >> N >> L; string str[110]; string concat = ""; for(i = 0; i < N ; i++) { cin >> str[i]; } sort(str,str+N); for(i = 0; i < N; i++) { concat += str[i]; } cout << concat << endl; return 0; }
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その4)
続き。ABC 087 B - Coinsの類題です。
- 複数あ座標を線分で結んだ時にその線分の距離が最大になる距離を求める
- 距離の公式を使う。
- かつ全ての線分を探索するため2重forループを使用。
#include <iostream> #include <cmath> using namespace std; int main() { int N,x[110],y[110],i,j,k; double maxdistance = 0; double xd,yd,distance; cin >> N; for(i = 0; i < N; i++) { cin >> x[i] >> y[i]; } for(j = 0;j < N;j++) { for(k = j; k < N; k++) { xd = pow(x[j] - x[k],2.0); yd = pow(y[j] - y[k],2.0); distance = sqrt(xd + yd); if(maxdistance <= distance) { maxdistance = distance; } } } cout << maxdistance << endl; return 0; }
- 指定された文字列が全て異なる文字で形成されているかどうかを判別
- 制約上全探索しても問題ないので単純にforループを回して同じ文字があるかどうかを判定
#include <iostream> #include <string> using namespace std; int main() { int i,j; string str; cin >> str; for(i = 0; i<str.length(); i++){ for(j = i + 1; j < str.length(); j++){ if(str[i] == str[j]){ cout << "no" << endl; return 0; } } } cout << "yes" << endl; return 0; }
ABC 051 B - Sum of Three Integers
- ある数値の範囲内におさまるx,y,zがある
- x + y + z = Sとなるx,y,zの組み合わせの数を算出する
- x,y,zを全てループで回してもよいが、時間的制約も気になるので、以下のようにプログラムを組んでみた
- x,yの値はforループ
- zの値はSからxとyを引いた値とする
- このzが決められた数値の範囲内でかつ0以上かどうかを判定
#include <iostream> using namespace std; int main() { int k,s,x,y,z; int counter = 0; cin >> k >> s; for(x = 0; x <= k;x++) { for(y = 0;y <= k; y++){ z = s - x - y; if(z >= 0 && z <= k) { counter++; } } } cout << counter << endl; return 0; }
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その3)
前回の続き。
ABC 081 B - Shift Onlyの類題を解きます。
ABC 068 B - Break Number
- 指定された数値を1ずつループで処理しながら2で割り切れる数をもとめる。
- max値とmaxカウンターを用意しておいて、そのカウンター以上割り切れる回数が多い数がでてきたら更新する。
#include <iostream> using namespace std; int main() { int i,j,input,counter; int max = 0; int maxcounter = 0; cin >> input; for(i = 1;i <= input; i++) { j = i; counter = 0; while(j > 1) { if(j % 2 == 0) { j /= 2; counter++; }else { break; } } if(counter >= maxcounter) { max = i; maxcounter = counter; } } cout << max << endl; return 0; }
ABC 073 B - Theater
- 団体客毎にループで処理
- 各ループ毎の人数を足し算していって、結果を出力
#include <iostream> using namespace std; int main() { int i,j,first,last,groups,counter,num_people; cin >> groups; for(i = 1; i <= groups; i++) { cin >> first >> last; counter += last - first + 1; } cout << counter << endl; return 0; }
ABC 072 B - OddString
- 入力された中から奇数番の文字のみ取得
- C++だとStringを配列としてもてるので、配列の番号で偶数番(配列は0からはじまるので)を文字列結合させる
#include <iostream> #include <string> using namespace std; int main() { string input; string output = ""; int i; cin >> input; for(i = 0; i < input.length(); i+=2) { output += input[i]; } cout << output << endl; return 0; }
ABC 053 B - A to Z String
- 文字列の中からAを見つけて、そこからZまでの長さの最大値をもとめる
- 何も考えずにAを見つけたら文字列の最後まで調べてZを見つけるなんてことをやったら時間オーバーになった
- よく考えれば最初にAを見つけたらその後にAがきたとしてもそれが最大の長さになるわけじゃないので、見つけ次第Zまでの長さを求めた後、break文を挟んだら通った。
#include <iostream> #include <string> using namespace std; int main() { string input; int i,j; int stringlength = 0; cin >> input; for(i = 0; i < input.length(); i++) { if(input[i] == 'A'){ for(j = i; j < input.length(); j++) { if(input[j] == 'Z') { stringlength = j - i + 1; } } break; } } cout << stringlength << endl; return 0; }
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その2)
前回の続き。
ABC 081 A - Placing Marbles の類題を解いていく。
ABC 079 A - Good Integer
- 4桁中上3桁または下3桁が同じ値であるか判別
- 数値を文字列として扱う
- 2桁目をcheck用にセットし、1と3桁目、または3と4桁目と同値かどうか調べる。
#include <iostream> using namespace std; int main() { string integer; char checkValue; cin >> integer; checkValue = integer[1]; if((integer[0] == checkValue && integer[2] == checkValue) || (integer[2] == checkValue && integer[3] == checkValue)) { cout << "Yes" << endl; } else { cout << "No" << endl; } return 0; }
ABC 085 A - Already 2018
- 文字列の一部を書き換える
- 意外とC++が一番簡単に書けるのでは??
#include <iostream> using namespace std; int main() { string date; cin >> date; date[3] = '8'; cout << date << endl; return 0; }
ABC 069 B - i18n
- 文字列から真ん中の文字を文字数に変換する
- C++だと文字列を配列として取れるので、文字数を取得したあと、
- 最初の文字
- 最後の文字
- 真ん中の文字数を取得
- そのあと文字列の結合を実行
#include <iostream> #include <string> using namespace std; int main() { string str,first,last,out; int strlength,middle; cin >> str; strlength = str.length(); first = str[0]; middle = strlength - 2; last = str[strlength - 1]; out = first + to_string(middle) + last; cout << out << endl; return 0; }
ABC 082 B - Two Anagrams
- 入力した2つの文字列をソート
- その際、1つ目は文字が小さい順(a to z)に、2つ目は大きい順(z to a)に並び替える・
- ソート後文字列を比較して2つ目のほうが辞書的に後の文字ならYes、逆ならNoと回答
- 全く同じ文字同士の比較が続いた場合、文字数が多いほうが辞書的に後になるので、文字数を比較したbool型のflag変数を使ってYes,Noを選択
- (変数の設定が汚いのはお許しください・・・(というより、よりよい変数の付け方を勉強しないと))
#include <iostream> #include <string> #include <algorithm> using namespace std; int main() { string anagram1,anagram2; int anagram1_size,anagram2_size; bool flag; cin >> anagram1; cin >> anagram2; anagram1_size = anagram1.length(); anagram2_size = anagram2.length(); flag = anagram1_size < anagram2_size; sort(anagram1.begin(),anagram1.end()); sort(anagram2.begin(),anagram2.end(),greater<int>()); for(int i = 0 ; i < min(anagram1_size,anagram2_size); i++) { if(anagram1[i] < anagram2[i]) { cout << "Yes" << endl; return 0; } else if (anagram1[i] > anagram2[i]) { cout << "No" << endl; return 0; } } if(flag) { cout << "Yes" << endl; } else { cout << "No" << endl; } return 0; }
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その1)
C, C++の勉強を兼ねて、
AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~
をやっていたのですが、10問終えたので、類題を解いていこうと思います。
まずは、ABC 086 A - Product の類題から。
- 倍数判定
- 3つの数字から3桁の数字を作り出して、4で割り切れるか判定
#include <iostream> using namespace std; int main() { int r,g,b; int integer; cin >> r >> g >> b; r *= 100; g *= 10; integer = r + g + b; if(integer % 4 == 0) { cout << "YES" << endl; } else { cout << "NO" << endl; } return 0; }
- 余り計算
- 500で割った時の余り(=500以下の数値)を出して、それがcoinsの数以下かどうか判定
#include <iostream> using namespace std; int main() { int yen,coins; int remain; cin >> yen; cin >> coins; remain = yen % 500; if(remain <= coins) { cout << "Yes" << endl; } else { cout << "No" << endl; } return 0; }
- 小数点以下の切り上げ
- キャストを使いながら、小数点以下の値がある場合に1繰り上げるように処理してみた
#include <iostream> using namespace std; int main() { int a,b,int_cast_avg; double avg; cin >> a >> b; avg = (a + b) / 2.0; int_cast_avg = (int)avg; if(int_cast_avg < avg) { int_cast_avg++; } cout << int_cast_avg << endl; return 0; }
エンジニアのためのマインドフルネス(という名の自分がやっていること)
TL,DR
マインドフルネスは時間の浪費じゃなくて投資。
My Spec
- 身長: 166cmをいったりきたり
- 体重: 60台半ばくらい
- BMI: 2じゅう・・・(ry
新しく始めたこと
- 運動(筋トレ、ランニング)
- 集中力を鍛える(瞑想、集中力カード)
- 姿勢
きっかけ
- 今年の正月に食べ過ぎで目に見えて太った。
- 去年秋の健康診断の結果が悪かった。
- 集中力が切れやすくなっていった(眠気、気づいたらネットサーフィンしてる)
運動
準備
実践
- 起床後
- お昼休み
- ジムでランニング(20分)、または図書館の行き帰りにウォーキング(40分)
集中力
瞑想
- 姿勢を正す(椅子に座ってても、あぐらをかいてても良い)
- 深呼吸をする(4秒吸って、4秒吐くくらいの気持ちで)
- 心を無にする(頭に何か浮かんだら浮かんだ自分を客観視する・20分~30分くらい)
集中力カード
完全にこの本の受け売り。
- URLにある黄色と青色でダイヤのような画像を使う
- 深呼吸(3秒吸う、2秒息を止める、6秒でゆっくり吐く) + 画像の中心点(黄色い丸点)を20秒くらいじっとみつめる
- 20秒後、目をつぶると見ていたダイヤ型の画像が浮かび上がるので、それが消えないようにする
姿勢
変化したこと
朝の目覚め
- どれだけ早く寝ても朝起きるのがしんどかったのに、今では朝の目覚めが抜群によくなった。(というか朝になれば勝手に目覚める)
- おかげで朝の貴重な時間を使うことができるように。
集中力
- 何をするにも集中がしやすくなった
- 読書のスピード向上
- 2~300Pくらいのビジネス書、基礎レベルの技術書なら2時間かからないくらい
- 英語の技術書、MOOCのような動画講義もある程度すらすら読み聞きできるようになった(昔は少し読むと頭が痛くなっていた)
- 仕事をダラダラやることがなくなった
- 仕事の生産性があがった(主観的)
- 読書のスピード向上
ポジティブシンキング
- 気持ちがある程度前向きになった
- クヨクヨ悩むことも少なくなり即断で動けるように
変わらないこと
た、体重、、、
- まだ1ヶ月くらいしかたっていないのでそんなもんかなと
- 落ち込むときもあるけど、「やらないよりは遥かにマシ」と言い続けている
- (筋肉が増えて、体脂肪が減っていることをただただ祈っている)
気をつけていること
無理をしない
- しんどい時はやらない
- 朝早い時、いつもより体調が悪そうな時は少し早めに切り上げる
毎日やる
- 週2で1時間より、毎日最低10分を心がけている(習慣化させるため)
これからの予定
最後に
これってマインドフルネスなのか?