Successfully reported this slideshow.                             Upcoming SlideShare
×

# 競技プログラミングにおけるコードの書き方とその利便性

6,594 views

Published on

Published in: Engineering
• Full Name
Comment goes here.

Are you sure you want to Yes No • Be the first to comment

### 競技プログラミングにおけるコードの書き方とその利便性

1. 1. 競技プログラミングにおける コードの書き方とその利便性 コーヤ・ロードアゲイン
2. 2. #1day1problem の発足 ● 主に1年生・2年生の競プロ力底上げ ● 初心者向けの典型問題とか投げてました
3. 3. ある日のM教授の忠告
4. 4. そういえば開始当初は… ● 1年生が分かるようにC言語縛り ● 1年生が分かるようにマクロなし縛り
5. 5. そういえば開始当初は…
6. 6. しばらくして ● HARDはC++を使わせるつもりで選んだり ● 簡単なマクロ(minとかmaxとか)は使ったり
7. 7. とはいえ ● 何人かはC++使えるっぽいし ● ぶっちゃけマクロ使いたいし
8. 8. そんなわけで ● 競プロ特有のコード例 ● その利便性 (大体「タイプ数が減る」) を紹介します
9. 9. /* 事前知識 */
10. 10. オブジェクト形式マクロ #define MAX 128 ● コンパイル前の処理(プリプロセッサ) ● プログラム中のMAXが128に置換される ● MAXIMAとか描いても128IMAにはならない int array[MAX]; // => int array; int r = MAXIMA; // => int r = MAXIMA;
11. 11. 関数形式マクロ #define SQR(x) x * x ● 関数っぽく置換される ● 本当にただ「置き換えるだけ」 int area = SQR(side); // => int area = side * side; int x = SQR(a + b); // => int x = a + b * a + b;
12. 12. 関数形式マクロ #define SQR(x) (x) * (x) ● 引数を()でくくると防げる ● 副作用があると相変わらず爆死 int x = SQR(a + b); // => int x = (a + b) * (a + b); int y = SQR(++j); // => int x = (++j) * (++j);
13. 13. インライン関数 inline int sqr(int x){ return (x * x * x); } ● 関数にinlineをつけるとインライン展開される ● 関数呼び出しのオーバーヘッドが0になる ● マクロと同様だが型安全、副作用にも比較的強い ● オプションをつけないとインライン展開されないことがある int y = sqr(++j); // => 期待通りに動く
14. 14. /* 本編 */
15. 15. 三項演算子 ● 短いif-elseが削れる ● 行数も減って全体が見通しやすい puts(is_uruu(y) ? “Yes” : “No”);
16. 16. 定数 const int INF = 100100100; const int MOD = (int)1e9 + 7; const double EPS = 1e-9; ● でかい数値で初期化する ● 剰余を求める問題 ● 幾何の微調整用(EPSより小さいと0と判定、とか)
17. 17. typedef typedef long long ll; ● 型の別名をつける(主にlong longがllになる) ● 短い名前をつけてタイプ数を減らす ll big_num;
18. 18. FOR/REP #define FOR(i, a, b) for (int i = (a); i < (b); ++i) #define REP(i, n) for (int i = 0; i < (n); ++i) ● for文簡略化のためのマクロ ● インクリメントするときのミスが減る for (int j = 0; j < n; ++i) // <- iではなくjが正解 REP(j, n) // => for (int j = 0; j < (n); ++j)
19. 19. bits/stdc++.h #include <bits/stdc++.h> ● ヘッダ全部盛り ● vectorもalgorithmもfunctionalも
20. 20. 短縮マクロ #define fst first #define pb push_back ● 短い vector<int> v; REP(i, n) v.pb(in());
21. 21. ALL #define ALL(obj) (obj).begin(), (obj).end() ● イテレータ簡略化のためのマクロ ● タイプ数が少ない ● コンテナじゃないと使えない sort(ALL(v)); // => sort(v.begin(), v.end());
22. 22. in template <class T = int> in(){ T x; cin >> x; return (x); } ● 宣言と同時に読み込みたい ● テンプレートなので色んな型に対応できる ● stdinより遅いので大量の入力には注意 int a = in(), b = in(); string s = in<string>();
23. 23. print template <class T> print(T& x){ cout << x << ‘n’; } ● printfの書式書くのダルい ● わざわざ明示的に改行するのダルい ● stdoutより遅いので(ry print(a / gcd(a, b) * b);
24. 24. debug #define debug(x) cerr << #x << “: “ << x << ‘n’ ● #xでxを文字列にできる ● cerrに出すことで普通の出力と区別 ● エラー出力を使うとダメなジャッジもあるので注意 double root2 = sqrt(2); debug(root2) // => “root2: 1.41421”
25. 25. cin/cout高速化 cin.tie(0); sync_with_stdio(false); ● cinとcoutの結びつけを解除 ● stdioとの同期をしない ● 入力と出力が非同期化される ● cinとstdin,coutとstdoutが混在するとバグる危険性がある
26. 26. usingエイリアス using template <class T> vec = vector<T>; using ll = long long; ● usingでエイリアスが設定できる ● テンプレートが使えるtypedef ● C++11以降でないと使えない vec<ll> v;
27. 27. 力が欲しいか… #define int long long ● intでオーバーフローした時の切り替え用 ● 強すぎる力にmain関数が耐えられない ● メモリ食い過ぎに注意(普通そんなに食わないけど) int x; // => long long x; int fact(int n) // => long long fact(long long n)
28. 28. signed main signed main() ● signedはintのこと ● main関数を保護することで強大な力を遺憾なく発揮できる
29. 29. 他にもいっぱい ● 紹介しきれないものたくさん ● くろこじのC++テンプレートのWiki ○ https://github.com/kurokoji/.cpp-Template/wiki ● 競プロ”圧倒的成長” Thanks to kurokoji(https://github.com/kurokoji)