さて、Mr.ExceptionのすずきさんがさっそうとProject EulerのProblem36を解いたらしいので、
僕も対抗心を燃やさせてください><。

Problem36、
最初に例。585 = 1001001001(binary)
このように10進数と2進数でともに回文になる数を1,000,000以下の整数の中から求めよ。

それぞれの桁をA(n),A(n-1),A(n-2),...,A(2),A(1),A(0)と表せば、
585はA(2)=5, A(1)=8, A(0)=5
1001001001はA(9)=1, A(8)=0,...,A(1)=0,A(0)=1と表せますね。

そして、回文であると言うことは
最上位桁の仮数と、最下位桁の仮数
最上位桁-1の仮数と、最下位桁+1の仮数
最上位桁-2の仮数と、最下位桁+2の仮数
がそれぞれ等しいということです。

式で書くと、(10進数の場合)

floor( A(n)/10^n ) % 10 == floor( A(0) ) % 10
floor( A((n-1))/10^(n-1) ) % 10 == floor( A(1)/10^1 ) % 10
floor( A((n-2))/10^(n-2) ) % 10 == floor( A(2)/10^2 ) % 10
...

と、最上位桁と最下位桁から両方1つずつ歩み寄っていくわけです
2進数の場合も基数を変えるだけです。

偶数桁なら丁度半分まで進みますし、
奇数桁なら中心の仮数は無視できるので、
floor(n/2)回の操作になります。

source.

template<int RADIX>
int power(int N)
{
	if( N >= 1 )		{ return RADIX * power<RADIX>(N-1); }
	else if( N == 0 )	{ return 1; }
	else			{ assert(false); return -1; }
}

template<int RADIX>
bool mirror_cmp(int figure, int num)
{
	using namespace pstade::oven;

	PSTADE_OVEN_FOREACH(i, counting(0,figure/2)) {
		if( (num / power<RADIX>(figure-i-1)) % RADIX != (num / power<RADIX>(i)) % RADIX ) { return false; }
	}
	return true;
}

桁数nがsource中ではfigureになっている点に注意.
powerは見ての通り、再帰ですね。

桁数を求める部分です

template<int RADIX>
int get_figure(int num)
{
	assert(num > 0);
	int count = 0;
	while( (num = num / RADIX) ) { ++count; }

	return ++count;
}

これは、対数なりなんなりを使った方が早いのかもしれません。。。ただし実際に桁の上昇に大して
この関数の計算量も対数時間でしか増えませんのでね。

メイン関数です

int main()
{
	using namespace pstade::oven;
	const int MAX_NUM = 1000000; //1,000,000 [1million]

	int sum = 0;
	PSTADE_OVEN_FOREACH(n, 	counting(1, MAX_NUM)) {
		if( 
			mirror_cmp<10>( get_figure<10>(n), n ) &&
			mirror_cmp<2>( get_figure<2>(n), n ) )
		{ sum += n; }
	}

	std::cout << sum << std::endl;
	return 0;
}

使ったヘッダ

#include <iostream>
#include <pstade/oven/foreach.hpp>
#include <pstade/oven/counting.hpp>
#include <cassert>
#include <vector>

visual studio2008 SP1で確認
次回、ちょっと不満がある点を直しましょう。