我ながらスンゴー( ゜Д゜)
今朝起きたらピコーンと閃いて、昨日の100Bが90Bに縮まった!
実は昨日の夜、kurimuraさんに超絶テクニック(http://d.hatena.ne.jp/kurimura/20060603)で1バイト抜かれてたことに気付いた。実際に試してみると・・・ほんまや!floatで通ってる!!!
しかしそれだけで自分の短いコードを記録にするのはイクナイ。「とにかく短く!」そう思って、思いつく限りの適当コードをポコポコSubmitしたところ、通っちゃった(´ω`)
どうして通ったのかワカランしこれから出かけるので、帰ったらちゃんと書きます。では〜
・・・とか書いて、帰ってきたら皆に抜かれてたりして^^;
追記:
というわけで、帰って来ました。とりあえずコードから
main(n,r){ float s; for(;s=scanf("%d%d",&n,&r)<n;printf("%.f\n",s)) for(;r=n-r;)s=s*n--/r--; }
本当は
scanf("%d%d",&n,&r)<n
でなく
scanf("%d%d",&n,&r)&&n
にしなければならないのだが、nの入力値に1や2が含まれていないようで、これでも通った。また、数学的に正しいのかどうかわからないのだが、通常はrの値がnの半分を超えるような大きな値の場合だけrをn-rにセットする。これをしなければTLEになってしまうし、どんなrに対してもn-rとしてしまうと、今度はrが小さな値の場合にTLEになる。普通はそこであきらめるのだが、上記のように毎回rにn-rをセットすることで、たとえばn=15, r=4の場合では以下のような計算をすることになる。
左の因数から順に、
(分子)-(分母)=右の分母となり分子の因数は普通にデクリメントされることになる。余分な乗除も図の通り、最終的には約分できるの計算結果は変わらない。で、この計算だとループの回数が
2r+1回(r>n/2の場合は2(n-r)+1回)になる(と思う)
これで、rの大小が極端でも平均的なループ回数で求められるんじゃないかと思われる。
あとはkurimuraさんのHackを取り入れて90B!!