这个题目是搜索指定矩阵中判断是否存在立方体的展开图,看似简单,其实情况复杂。
当然,如果你很懂立方体的展开图,这就是一道水题。
接下来说下立方体展开图的知识:
立体图形的相关问题可以转化为平面图形来研究,但是我的空间想象能力较差,只有通过探索总结出规律才能解决问题。
一、立方体平面展开图中的特点
1、当我们从立方体的某顶点出发,最多只能观察到三个面,这三个面中必包括三组相对面中的各一个,且两个相对的面不能被同时看到。
2、平面展开图形中的每一个正方形至少有一边与其他正方形相连。
3、立方体的平面展开图中一个公共顶点处最多只能出现三个正方形,与一个正方形相邻的正方形最多只能有四个。
4、立方体中原来处于相对位置上的两个面,展开后的正方形无公共顶点和公共边;反之,有公共顶点或公共边的两个正方形折叠成立方体后,必成为相邻面,不可能成为相对面。
二、立方体平面展开图的形式
立方体由6个大小完全相同的正方形组成,由于选择剪开的棱不一样,所以表面展开图有11种,可归类为:“141”型、“132”型、“222”型、“33”型四种。凡是出现“田”字形的一定不是,凡是出现“凹”字形的也一定不是,五连长链和六连长链均不是立方体的表面展开图。巧记立方体展开图,有一首小儿歌 。
中间4个一连串,两边各一随便放。
二三紧连错一个,三一相连一随便。
两两相连各错一,三个两排一对齐。
要找两个相对面,切记相隔一个面
示意图如上,当然还要考虑左右上下翻转的情况。
我是采用类似滤波器的暴力匹配,大神请忽略我。
代码如下:
#include <stdio.h>
#include <iostream>
using namespace std;
int result[15] = {411,6,6,6,6,6,6,6,6,6,6,6,6,6,6};
int filter1[15][4][3] =
{
//1
{
{10,100,1},
{10,100,1},
{10,100,1},
{10,100,1}
}
//2
,
{
{0,0,1},
{1,1,1},
{0,1,0},
{0,1,0}
}
//3
,
{
{0,1,0},
{0,1,0},
{1,1,1},
{0,0,1}
}
//4
,
{
{1,0,0},
{1,1,1},
{0,1,0},
{0,1,0}
}
//5
,
{
{0,1,0},
{0,1,0},
{1,1,1},
{1,0,0}
}
//6
,
{
{0,0,1},
{0,1,1},
{1,1,0},
{0,1,0}
}
//7
,
{
{0,1,0},
{0,1,1},
{1,1,0},
{1,0,0}
}
//8
,
{
{1,0,0},
{1,1,0},
{0,1,1},
{0,1,0}
}
//9
,
{
{0,1,0},
{1,1,0},
{0,1,1},
{0,0,1}
}
//10
,
{
{0,0,1},
{0,1,1},
{0,1,0},
{1,1,0}
}
//11
,
{
{0,1,1},
{0,1,0},
{1,1,0},
{1,0,0}
}
//12
,
{
{1,0,0},
{1,1,0},
{0,1,0},
{0,1,1}
}
//13
,
{
{1,1,0},
{0,1,0},
{0,1,1},
{0,0,1}
}
//14
,
{
{0,0,1},
{0,1,1},
{1,1,0},
{1,0,0}
}
//15
,
{
{1,0,0},
{1,1,0},
{0,1,1},
{0,0,1}
}
};
int filter2[15][3][4] =
{
{
{1,1,1,1},
{100,100,100,100},
{10,10,10,10}
}
//
,
{
{1,1,0,0},
{0,1,1,1},
{0,1,0,0}
}
,
{
{0,0,1,0},
{1,1,1,0},
{0,0,1,1}
}
,
{
{0,0,1,1},
{1,1,1,0},
{0,0,1,0}
}
,
{
{0,1,0,0},
{0,1,1,1},
{1,1,0,0}
}
//
,
{
{1,1,0,0},
{0,1,1,1},
{0,0,1,0}
}
,
{
{0,1,0,0},
{1,1,1,0},
{0,0,1,1}
}
,
{
{0,0,1,1},
{1,1,1,0},
{0,1,0,0}
}
,
{
{0,0,1,0},
{0,1,1,1},
{1,1,0,0}
}
//
,
{
{1,1,0,0},
{0,1,1,1},
{0,0,0,1}
}
,
{
{1,0,0,0},
{1,1,1,0},
{0,0,1,1}
}
,
{
{0,0,1,1},
{1,1,1,0},
{1,0,0,0}
}
,
{
{0,0,0,1},
{0,1,1,1},
{1,1,0,0}
}
//
,
{
{1,1,0,0},
{0,1,1,0},
{0,0,1,1}
}
,
{
{0,0,1,1},
{0,1,1,0},
{1,1,0,0}
}
};
int filter3[2][2][5] =
{
{
{1,1,1,0,0},
{0,0,1,1,1}
}
,
{
{0,0,1,1,1},
{1,1,1,0,0}
}
};
int filter4[2][5][2] =
{
{
{0,1},
{0,1},
{1,1},
{1,0},
{1,0}
}
,
{
{1,0},
{1,0},
{1,1},
{0,1},
{0,1}
}
};
int main()
{
int flag;
int i;
int j;
int k;
int sum;
int m;
int n;
char temp;
int board[11][11];
int counter = 0;
while(cin>>temp)
{
counter++;
flag = 0;
if(temp == 'r')
{
board[0][0] = 1;
}
else
{
board[0][0] = 0;
}
for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
if(i == 0 && j == 0)
{
;
}
else
{
scanf("%c", &temp);
if(temp == 'r')
{
board[i][j] = 1;
}
else
{
board[i][j] = 0;
}
}
}
scanf("%c", &temp);
}
//for(i = 0; i < 10; i++)
//{
// for(j = 0; j < 10; j++)
// printf("%d", board[i][j]);
// printf("\n");
//}
for(k = 0; k < 15 && flag != 1; k++)
{
for(i = 0; i < 10 && flag != 1; i++)
{
for(j = 0; j < 10 && flag != 1; j++)
{
if(i + 2 < 10 && j + 3 < 10)
{
sum = 0;
for(m = 0; m < 3; m++)
{
for(n = 0; n < 4; n++)
{
sum += filter2[k][m][n] * board[i + m][j + n];
}
}
}
if(sum == result[k])
{
//printf("match %d@@@%d %d\n", k, i, j);
flag = 1;
sum = 0;
break;
}
}
}
}
for(k = 0; k < 15 && flag != 1; k++)
{
for(i = 0; i < 10 && flag != 1; i++)
{
for(j = 0; j < 10 && flag != 1; j++)
{
if(i + 3 < 10 && j + 2 < 10)
{
sum = 0;
for(m = 0; m < 4; m++)
{
for(n = 0; n < 3; n++)
{
sum += filter1[k][m][n] * board[i + m][j + n];
}
}
}
if(sum == result[k])
{
//printf("match %d@@@%d %d\n", k, i, j);
flag = 1;
sum = 0;
break;
}
}
}
}
for(k = 0; k < 2 && flag != 1; k++)
{
for(i = 0; i < 10 && flag != 1; i++)
{
for(j = 0; j < 10 && flag != 1; j++)
{
if(i + 1 < 10 && j + 4 < 10)
{
sum = 0;
for(m = 0; m < 2; m++)
{
for(n = 0; n < 5; n++)
{
sum += filter3[k][m][n] * board[i + m][j + n];
}
}
}
if(sum == 6)
{
//printf("match %d@@@%d %d\n", k, i, j);
flag = 1;
sum = 0;
break;
}
}
}
}
for(k = 0; k < 2 && flag != 1; k++)
{
for(i = 0; i < 10 && flag != 1; i++)
{
for(j = 0; j < 10 && flag != 1; j++)
{
if(i + 4 < 10 && j + 1 < 10)
{
sum = 0;
for(m = 0; m < 5; m++)
{
for(n = 0; n < 2; n++)
{
sum += filter4[k][m][n] * board[i + m][j + n];
}
}
}
if(sum == 6)
{
//printf("match %d@@@%d %d\n", k, i, j);
flag = 1;
sum = 0;
break;
}
}
}
}
if(flag == 1)
{
printf("Board %d: red squares can be folded into a cube\n", counter);
}
else
{
printf("Board %d: impossible\n", counter);
}
}
return 0;
}