カメヲラボ

主にプログラミングとお勉強全般について書いてます

Sum of Factorials(2)

まずは普通に

前回書いたトラップを回避するためにとりあえず単純にコードを書いてみて、それを短縮していくことにする。


main(){
int n,i,k;

for(;scanf("%d",&n),n>=0;){

if(n==0){
puts("NO");
continue;
}//nが最初から0のときはNOを出力

for(i=9,k=362880;n>0&&i>0;){
if(n>=k)n-=k;
k/=i--;
if(i==0&&n==1)n=0;//0!=1なので残りが1でもYES
}

puts(n?"NO":"YES");
}
}


上記のコードで、コメントをつけている部分が無駄な所。どんな問題であれ、出力は基本的に1箇所にまとめることを心掛ければ自然にコードは短くなる。また、0とか1の微妙な判定は計算順序をきちんと整理してやれば無駄な条件分岐を書く必要もなくなるのだ。


入力が0のときはループに入る直前で、必ずNOになる値(負の数等)に置き換えてしまえば問題ないし、0!についてもループの終了判定直前で減算していれば、わざわざ分けて書く必要も無くなる。


すなわち、


for(①;②;④)③;
のステップだけでなく、
for(①;②,③;⑤)④;
のように利用するということである。