NERC 2015 Hypercube 题解

NERC 2015 Hypercube 题解

题目意思非常简单。判定一个三维图形能否拼成一个超立方体。不要问我超立方体长啥样

我们回忆一下三维展开怎么做。

假设一个正方体展开图像下面这样:

.......
..e....
.abcd..
..f....
.......

则我们钦定正方体的底面为b,则我们在每一个位置放上一个正方体,然后滚动到b。可以发现那些地面恰好构成一个正方体$Leftrightarrow $底面互不相同。

我们可以尝试用一个三元组来表示一个滚动状态:(a,b,c),表示在前后,左右,上下方向是哪一个面,根据上下/前后/左右来取正负。钦定一个正方体的前,右,上为A,B,C。则初始状态为((A,B,C))

向前滚动为((A,-B,C))。。。

这样每一个三元组可以映射到唯一的三元组。

这样也可以扩展到四维。

const int MAXN=10;
int n,m,k;
char C[MAXN][MAXN][MAXN];
map<int,int> M;
bool vis[MAXN][MAXN][MAXN];
void dfs(int x,int y,int z,int a,int b,int c,int d){
	if(vis[x][y][z]) return ;
	vis[x][y][z]=true;
	if(M.find(d)!=M.end()){	
		puts("No");exit(0);
	}
	M[d]=1;
	if(C[x+1][y][z]=='x') dfs(x+1,y,z,d,b,c,-a); 
	if(C[x-1][y][z]=='x') dfs(x-1,y,z,-d,b,c,a);
	if(C[x][y+1][z]=='x') dfs(x,y+1,z,a,d,c,-b);
	if(C[x][y-1][z]=='x') dfs(x,y-1,z,a,-d,c,b);
	if(C[x][y][z+1]=='x') dfs(x,y,z+1,a,b,d,-c);
	if(C[x][y][z-1]=='x') dfs(x,y,z-1,a,b,-d,c);
}
int main(){
	scanf("%d%d%d",&m,&n,&k);
	rb(i,1,k)
		rb(j,1,n)
			rb(l,1,m) cin>>C[i][j][l];
	rb(i,1,k) rb(j,1,n) rb(l,1,m) if(C[i][j][l]=='x'){
		dfs(i,j,l,1,2,3,4);
		puts("Yes");
		return 0;
	}
	return 0;
}

原文地址:https://www.cnblogs.com/gary-2005/p/14139736.html