SRM462 Div1 Easy(250), Div2 Medium(500) AgeEncoding
基数が大きくなるほど表す年齢も大きくなるので、二分探索。例外処理が面倒。
蝋燭が0000ならば、-1。蝋燭が0001のとき年齢が1ならば-2、年齢が1以上ならば-1。蝋燭が0101のように最後の1本と他に1本以上立っていて、年齢が1ならば-1。
#include <string> using namespace std; class AgeEncoding { double check( string candle, double base ); public: double getRadix( int age, string candlesLine ); }; double AgeEncoding::getRadix( int age, string candlesLine ) { // 例外 int n = (int)candlesLine.size(); int num = 0; // 最後の1本を除く蝋燭の本数 for ( int i=0; i<n-1; i++ ) if ( candlesLine[i] == '1' ) num++; if ( num == 0 && candlesLine[n-1] == '0' ) { return -1; } else if ( num == 0 && candlesLine[n-1] == '1' ) { if ( age == 1 ) return -2; else return -1; } else if ( num > 0 && candlesLine[n-1] == '1' ) { if ( age == 1 ) return -1; } // 二分探索 double l = 0; double r = age; for ( int i=0; i<100; i++ ) { double m = ( l + r ) / 2; if ( check( candlesLine, m ) < age ) l = m; else r = m; } return r; } // 基数baseでcandleが表す年齢を返す double AgeEncoding::check( string candle, double base ) { double a = 0; double b = 1; for ( int i=(int)candle.size()-1; i>=0; i-- ) a += b * (candle[i]-'0'), b *= base; return a; }