A問題
for文を使わない
A問題はfor文なしで解けます。
入力は最大で4文字なので、if文を列挙しても時間はかかりません。
例題:ABC175A
↑ Rが何回続いたのかを判定する問題です。if文を使えば、Rが続いた回数で場合分けできます。
切り上げ
覚え方は「切って上げる」。-1で切って、割る数で上げる。覚えるのが面倒ならマクロを作りましょう。
例題:ABC157A
Q:Nページの書類を両面印刷すると、最小で何枚の紙が必要か
//ans = (N-1+2)/2;
# define dup(x,y) (((x)+(y)-1)/(y))
ans = dup(n,2);
大きいほうを選ぶときは、ifよりmax
//if(a > b) ans = a; // コードが長いです。
//else ans = b; // コードが長いです。
ans = max(a,b); // 1行でかけます。
Yes,Noの出力はマクロ
# define yn {puts("Yes");}else{puts("No");}
if(a >= 30) yn; // 入力が30以上ならYes。未満ならNo。
B問題
小数点
小数点は誤差の温床。不要な割り算は使わないようにしましょう。掛け算にすればOKです。
//if(sqrt(a*a + b*b) == c) //小数が出る
if(a*a + b*b == c*c) // 小数が出ない
小数を出力する問題は桁数に注意しましょう。多めに出力する分には問題ないので、どーんと大きくいきましょう。「正しい値との絶対誤差または相対誤差が 10^(−9) 以下であれば正解とみなされる」なら、15桁くらい出しておきましょう。
ギリギリを狙うとWAが出るので注意。
# define shousuu cout << fixed << setprecision(15);
shousuu; // 以降の出力が小数点以下15桁になる。
オーバーフロー
数が大きくなりそうなら、intではなくlonglongを使いましょう。マクロを使うとllで省略できます。
llでもオーバーフローするなら、割り算にしましょう。
例題:ABC169B
//ans *= a; // そのまま掛け算するとオーバーフローする場合は……
const ll LINF = 1001002003004005006ll;
if(ans < LINF / a) ans *= a; // オーバーフローしないかチェックしてから、掛け算をする。
C問題
コーナーケースを確認する。
例題が全部通っても過信してはいけない。
超便利なset
setは2つの機能を持っています。
・重複した値の削除
・昇順ソート
「同じ要素があるか答えよ」という問題はもちろんですが「条件を満たす数を列挙せよ」という問題にも役立ちます。例えば「Nの約数を列挙せよ」という問題の場合、通常なら重複をif文で除外して昇順ソートが必要ですが、setなら一発です。
重複なしループ
例えば「異なる数や点を3つ選び、条件を満たしているものの個数を求める」といった問題に使えます。
rep(i,n) rep(j,i) rep(k,j)
解けなかったらD問題へ
CよりDが簡単なこともあります。DよりEが簡単なときもあります。
(自分はまだ一度も体験してませんが)
勉強用の記事
Visual Studio Codeで競プロ環境構築
AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~
レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【初級編:競プロを始めよう】
レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編:目指せ水色コーダー!】