1201-Lattice Practices

問題概要

問題文の図のように噛み合うような配置の個数を求めよ.
ただし,回転・反転は同じものと見なす.

解法

下の部分のみを全部定めて探索する.
回転・反転も数えるので最後に結果を8で割る.

実装(C++)

#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

typedef long long int lli;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define rep(i,s,x) for(int i=s;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=(x);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
char in[10][6];
char rev[10][6];
bool rev_equal[10];
bool input(){
	for(int i=0;i<10;i++){
		cin>>in[i];
		if(in[i][0]=='E')return false;
		REP(j,5){
			rev[i][4-j]=in[i][j];
		}
		rev_equal[i]=true;
		REP(j,5){
			if(rev[i][j]!=in[i][j]){
				rev_equal[i]=false;
				break;
			}
		}
	}
	return true;
}
char MAP[5][5];
void show(){
	REP(j,5){
		REP(i,5){
			cout<<MAP[i][j];
		}
		cout<<endl;
	}
	cout<<endl;
}
bool used[10];
int dfs(int k){
	int res=0;
	if(k==5){
		REP(i,10){
			if(!used[i]){
				bool ok=false;
				REP(j,5){
					bool pok=true;
					REP(l,5){
						if(MAP[l][j]==in[i][l]){
							pok=false;break;
						}
					}
					if(pok){
						ok=true;
						break;
					}
					pok=true;
					REP(l,5){
						if(MAP[l][j]==rev[i][l]){
							pok=false;break;
						}
					}
					if(pok){
						ok=true;
						break;
					}
				}
				if(!ok)return 0;
			}
		}
		return 1;
	}else{
		REP(i,10){
			if(!used[i]){
				used[i]=true;
				REP(j,5){
					MAP[k][j]=in[i][j];
				}
				res+=dfs(k+1);

				if(rev_equal[i]){
					used[i]=false;
					continue;
				}

				REP(j,5){
					MAP[k][j]=rev[i][j];
				}
				res+=dfs(k+1);

				used[i]=false;
			}
		}
	}
	return res;
}
int main(){
	while(input()){
		cout<<dfs(0)/8<<endl;
	}
}