SRM 501 250pt: FoxPlayingGame
問題概要
あなたのスコアは最初0.0です。スコアにa(-2.0
解法
a,bがそれぞれ正負の場合とbについては1より小さいか大きいかとか考えて場合分けで書いたのが以下のコード。Acceptはされたけど、こういう場合分けを書きまくるのはミスを誘発して良くない。計算時間が許すのであれば全部試すのが一番良い。どうせ最大値になるのは、nA*a*b^nB, nA*a*b^(nB-1), nA*a*b, nA*aしかないのだからそのMaxを返すべきだった。ちなみにnA,nBが大きくないのでDPでも解ける(上位陣はDP派が多かったような印象)。
感想
「そうそう、昔はこんな難易度のeasyだったよなあ…」とかぼんやり考えながらコーディングしていたら変数名間違えて再提出してしまった。おまけにそれ以外にもミスがあって(nB=0の分かりやすいコーナーケース)合計3回位再提出した。
本番中に提出したコード
class FoxPlayingGame { public: double theMax(int nA, int nB, int paramA, int paramB) { double a = (double)paramA/1000.0, b = (double)paramB/1000.0; if(nB==0) return nA*a; if(a==0){ return 0; } if(b==0 ){ if(a>0) return nA*a; else return 0; } if(a > 0 && b > 0){ if(b > 1){ double ret = nA*a; for(int i=0; i<nB; i++) ret *= b; return ret; } else{ return nA*a; } } if(a < 0 && b < 0){ if(fabs(b) > 1){ double ret = nA*a; for(int i=0; i<nB-((nB&1)?0:1); i++){ ret *= b; } return ret; } else{ double ret = nA*a; ret *= b; return ret; } } if(a > 0 && b < 0){ if(fabs(b) > 1){ double ret = nA*a; for(int i=0; i<nB-(nB&1); i++){ ret *= b; } return ret; } else{ return nA*a; } } if(a < 0 && b > 0){ if(fabs(b) < 1){ double ret = nA*a; for(int i=0; i<nB; i++){ ret *= b; } return ret; } else{ return nA*a; } } }
自分が書くべきだったコード
class FoxPlayingGame { public: double theMax(int nA, int nB, int paramA, int paramB) { double a = (double)paramA/1000.0, b = (double)paramB/1000.0; double sum = nA*a, ret = sum; if(nB>0) ret = max(ret, sum*b); if(b!=0 && nB>0) ret = max(ret, sum*pow(b,nB-1)); ret = max(ret, sum*pow(b,nB)); return ret; }