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;
}