题目来源:http://poj.org/problem?id=1052

题目大意:

  把1*1*1的小立方体通过粘接相邻面组成大的立方体的形状。如下图所示:

  一层一层地堆叠,立方体从三个方向的投影会分别形成三个字母的形状:"E" "G" "B"

  科学家们想知道哪些投影形状的组合是可能出现的。写一个程序判断给定的投影图形组合是否可能出现。

输入:由一系列数据集组成。每个用例第一行为一个整数n(1<=n<=20),表示大立方体的边长。接下来的3*n行为给出的投影图形。每n行表示一个面的投影,'X'表示产生了影子,'-'表示光线穿过。n为0时表示输入结束。

输出:如果给出的组合可能产生,输出:Valid set of patterns 否则输出 Impossible combination 格式见sample.


Sample Input

5
XXXXX
X----
X--XX
X---X
XXXXX
XXXXX
X----
XXXXX
X----
XXXXX
XXXXX
X---X
XXXX-
X---X
XXXXX
3
X--
-X-
--X
XX-
XXX
-XX
-XX
XXX
XX-
0

Sample Output

Data set 1: Valid set of patterns
Data set 2: Impossible combination

本题也属于模拟吧。首先需要把题目看懂。

首先,对于每个给出的投影图像,可能对应8种情况:通过旋转和镜像的变换得到。那么三个面总共有8*8*8种组合,枚举所有的组合,能找到符合条件的立方体能说明组合是可能出现的,否则不可能。

通过正向构造立方体比较麻烦,可以用“逆向”的方法。具体来说,首先根据给定的立方体大小,首先初始化一个完整的立方体。然后对于投影图形中被光线穿透的格子,“挖”去立方体对应的部分。

然而对每个面这样处理后得到的残留图形并不一定还能形成给定的三个投影,所以需要检验。除了检验投影还要检验它的连通性(dfs)。

代码中循环很多,要小心。

 //////////////////////////////////////////////////////////////////////////
// POJ1052 Plato's Blocks
// Memory: 396K Time: 16MS
// Language: C++ Result: Accepted
////////////////////////////////////////////////////////////////////////// #include <iostream> using namespace std;
int n;
int face[][][][];
int cube[][][];
int visited[][][]; bool input() {
cin >> n;
if (n == ) return false;
char c;
for (int t = ; t < ; ++t) {
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
cin >> c;
if (c == 'X') face[t][][i][j] = ;
else face[t][][i][j] = ;
}
}
}
return true;
} void r_m() {
//rotation
for (int t = ; t < ; ++t) {
for (int k = ; k <= ; ++k) {
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
face[t][k][i][j] = face[t][k - ][j][n - i - ];
}
}
}
}
//mirror
for (int t = ; t < ; ++t) {
for (int k = ; k < ; ++k) {
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
face[t][k + ][i][j] = face[t][k][i][n - j - ];
}
}
}
}
} void MakeCube(int a, int b, int c) {
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
if (face[][a][i][j] == ) {
for (int k = ; k < n; ++k) {
cube[i][j][k] = ;
}
}
}
}
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
if (face[][b][i][j] == ) {
for (int k = ; k < n; ++k) {
cube[k][i][j] = ;
}
}
}
}
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
if (face[][c][i][j] == ) {
for (int k = ; k < n; ++k) {
cube[i][k][j] = ;
}
}
}
}
} bool check(int a, int b, int c) {
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
if (face[][a][i][j] == ) {
bool flag = ;
for (int k = ; k < n; ++k) {
if (cube[i][j][k]) {
flag = ;
break;
}
}
if (flag == ) {
return false;
}
}
}
}
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
if (face[][b][i][j] == ) {
bool flag = ;
for (int k = ; k < n; ++k) {
if (cube[k][i][j]) {
flag = ;
break;
}
}
if (flag == ) {
return false;
}
}
}
}
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
if (face[][c][i][j]) {
bool flag = ;
for (int k = ; k < n; ++k) {
if (cube[i][k][j]) {
flag = ;
break;
}
}
if (flag == ) {
return false;
}
}
}
}
return true;
} void dfs(int i, int j, int k) {
if (i < || i >= n || j < || j >= n || k < || k >= n) {
return ;
}
if (cube[i][j][k] == || visited[i][j][k] == ) {
return;
}
visited[i][j][k] = ;
dfs(i - , j, k);
dfs(i + , j, k);
dfs(i, j - , k);
dfs(i, j + , k);
dfs(i, j, k - );
dfs(i, j, k + );
} bool connectivity() {
memset(visited, , sizeof(visited));
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j) {
if (cube[i][j][]) {
dfs(i, j, );
for (int a = ; a < n; ++a) {
for (int b = ; b < n; ++b) {
for (int c = ; c < n; ++c) {
if (cube[a][b][c] && visited[a][b][c] == ) {
return false;
}
}
}
}
return true;
}
}
}
} bool IsValid() {
r_m();
for (int i = ; i < ; ++i) {
for (int j = ; j < ; ++j) {
for (int k = ; k < ; ++k) {
memset(cube, , sizeof(cube));
MakeCube(i, j, k);
if (check(i, j, k) && connectivity()) {
return true;
}
}
}
}
return false;
} int main(void) {
int case_id = ;
while (input()) {
cout << "Data set " << ++case_id << ": ";
if (IsValid()) {
cout << "Valid set of patterns" << endl;
} else {
cout << "Impossible combination" << endl;
}
}
system("pause");
return ;
}

POJ1052 Plato's Blocks的更多相关文章

  1. POJ 1052 Plato's Blocks

      Plato's Blocks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 734   Accepted: 296 De ...

  2. POJ题目排序的Java程序

    POJ 排序的思想就是根据选取范围的题目的totalSubmittedNumber和totalAcceptedNumber计算一个avgAcceptRate. 每一道题都有一个value,value ...

  3. POJ题目细究

    acm之pku题目分类 对ACM有兴趣的同学们可以看看 DP:  1011   NTA                 简单题  1013   Great Equipment     简单题  102 ...

  4. 【转】POJ百道水题列表

    以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...

  5. 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM

    刚过去的周五(3-14)例行地主持了技术会议,主题正好是<UI层的设计模式——从Script.Code Behind到MVC.MVP.MVVM>,是前一天晚上才定的,中午花了半小时准备了下 ...

  6. 【POJ-1390】Blocks 区间DP

    Blocks Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5252   Accepted: 2165 Descriptio ...

  7. 开发该选择Blocks还是Delegates

    前文:网络上找了很多关于delegation和block的使用场景,发现没有很满意的解释,后来无意中在stablekernel找到了这篇文章,文中作者不仅仅是给出了解决方案,更值得我们深思的是作者独特 ...

  8. poj 1390 Blocks

    poj 1390 Blocks 题意 一排带有颜色的砖块,每一个可以消除相同颜色的砖块,,每一次可以到块数k的平方分数.问怎么消能使分数最大.. 题解 此题在徐源盛<对一类动态规划问题的研究&g ...

  9. Java 同步代码块 - Synchronized Blocks

    java锁实现原理: http://blog.csdn.net/endlu/article/details/51249156 The synchronized keyword can be used ...

随机推荐

  1. CIA泄露资料分析(黑客工具&技术)—Windows篇

    背景 近期,维基解密曝光了一系列据称来自美国中央情报局(CIA)网络攻击活动的秘密文件,代号为“Vault 7”,被泄露文件的第一部分名为“Year Zero”,共有8761个文件,包含7818个网页 ...

  2. 问题:只能在执行 Render() 的过程中调用 RegisterForEventValidation;结果:只能在执行 Render() 的过程中调用 RegisterForEventValidation

    只能在执行 Render() 的过程中调用 RegisterForEventValidation 当在导出Execl或Word的时候,会发生只能在执行 Render() 的过程中调用 Register ...

  3. C# WinForm中如何让当前应用程序只允许启动一个实例

    我们在WinForm开发中,很多情况下是需要只允许让用户运行一个实例,那么代码其实很简单.只需要修改Program.cs文件,代码如下 static class Program { /// <s ...

  4. CentOS7:ifconfig command not found解决和netstat -an

    没有 ifconfig 和netstat -an 的话安装 net-tools package yum install net-tools

  5. 3DPDF是个什么东西?

    就是可以把3D模型放入到PDF中,然后客户可以直接用adobe reader查看这个PDF.经过搜索发现,大多数PDF编辑软件都没有直接把3D模型插入到PDF中的功能. 很多是3D软件自身提供的,比如 ...

  6. python 删除正在for循环遍历的list正确做法

    先放一个python遍历发生的异常: ls =[1,2,3,4,5,6,7,8,9] for i in ls: print("i",i) print("ls", ...

  7. CF938D Buy a Ticket

    这个题都想不出来,感觉

  8. 图(最短路径算法————迪杰斯特拉算法和弗洛伊德算法).RP

    文转:http://blog.csdn.net/zxq2574043697/article/details/9451887 一: 最短路径算法 1. 迪杰斯特拉算法 2. 弗洛伊德算法 二: 1. 迪 ...

  9. Cadence如何自定义快捷键

    第一步:将pcbenv复制到SPB_Data下,并覆盖原来的文件 第二步:打开pcbenv文件,将script和views文件夹以及env复制到cadence安装目录\SPB_16.3\share\p ...

  10. 预编译对象解决SQL注入问题