カメヲラボ

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

Poloar Explorer


2次元惑星(要するに図のような平面で考えましょうということ)上で、壊れた宇宙船を助けて帰ってこれるかという問題。与えられたインプットは、


①惑星の半径
(1〜100マイル)

②ガソリンの量
(0〜100ガロン)

③中心を原点と考えた時のスタート地点と事故現場のなす角
(0〜360度)

出力は、ガソリンが尽きずに帰ってこれればYES、ダメならNO。それと、消費したガソリンの量だ。ガソリンの消費量は、1ガロンあたり5マイルになっている。
往復に必要なガソリンの量は図のX,Zを使うと

2π*X*Z/360*2/5
ただし、惑星は円形なのでZが180度を超える場合は逆回りした方がガソリンの消費量が少ないので、そこだけは注意が必要だ。

それほど難しい問題ではないので、コード短縮の標的になりやすい。特に円周率とか自然対数のように精度が微妙な問題の場合はどんな定数を使うかでコードの長さが大きく変わってくる。

この問題で最初に気付いた点は、Zが180度を超えた場合の処理について。インプットの値が極端なのか、180度を超えた値といっても、360度か否かという判定だけで通った。つまり、

if(Z>360)Z-=180;

とか書く必要は無く、

Z%=360;

で済むということ。また、2π/360*2/5を予め計算しておくと0.00698...になるが、これは0.007で大丈夫だということ。この辺りを押さえつつ短縮していくと、116Bになった。

float X;Z;
main(Y){
  for(;scanf("%*s%f%d%d%*s",&X,&Y,&Z);printf("%s %d\n",X>Y?"NO":"YES",Z=X>Y?Y*5:Y-X))
    X*=Z%360*.007;
}

私の環境では~scanfとしないと終わらないが、PKUのシステムだと"~"はいらないようだ。
このコードで無駄なところは、floatで計算しているので最後に整数型にキャストが必要になること。私のコードではもう縮みそうに無いので、トップのnamasuteさんはint型だけでうまく切り抜けているんじゃないかと思う。