問題D Hexagram

解法

DFS(深さ優先探索)です。12個の数字の合計が3の倍数にならないときや直線4つの数字が3の倍数にならないときに枝刈りできます。数字が全部異なるため回転・対称のものは全部で12通りあるので、重複して数え上げて最後に12で割るとよいです。

コード(C++)

#include <iostream>
using namespace std;

int a[12], b[12], sum, line;
bool memo[12];

int dfs(int pos = 0){
	// 合計が 3 の倍数でないときは解は 0 
	if( sum % 3 != 0 ) return 0;
	
	if( pos == 12 ){
		if( line != a[1] + a[8] + a[9] + a[11] ) return 0;
		if( line != a[5] + a[7] + a[10] + a[11] ) return 0;
		return 1;
	}
	
	if( pos == 4 ){
		line = a[0] + a[1] + a[2] + a[3];
		if( sum / 3 != line ) return 0;
	}else if( pos == 7 ){
		if( line != a[3] + a[4] + a[5] + a[6] ) return 0;
	}else if( pos == 9 ){
		if( line != a[0] + a[6] + a[7] + a[8] ) return 0;
	}else if( pos == 11 ){
		if( line != a[2] + a[4] + a[9] + a[10] ) return 0;
	}
	
	int res = 0;
	for(int i = 0 ; i < 12 ; i++ ){
		if( memo[i] ) continue;
		
		a[pos] = b[i];
		memo[i] = true;
		res += dfs(pos + 1);
		memo[i] = false;
	}
	return res;
}

int main(){
	while( cin >> b[0], b[0] ){
		sum = b[0];
		for(int i = 1 ; i < 12 ; i++ ){
			cin >> b[i];
			sum += b[i];
		}
		
		fill(memo, memo + 12, false);
		cout << dfs() / 12 << endl;
	}
}