题目来源: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. 10-17C#语句(3)--跳转语句、异常处理语句

    回顾: 穷举法(重点掌握):虽然运用for...嵌循环语句,但是也要找到执行for...循环的规律, 即一个题目中,需要得到哪个值,首先定义它初始变量:哪个条件需要改变,它对应的就是for...循环的 ...

  2. c:if标签数据回显判断是否选中

    <form action="/brand/list.do" method="post" style="padding-top:5px;" ...

  3. 最全SDWebImage-3.8版本源码阅读详解

    一.前言 SDWebImage,非常友好的网络图片加载第三方框架,在GitHub中已经获得了15000++的star,链接地址:https://github.com/rs/SDWebImage 本人分 ...

  4. DAY11-MYSQL补充之SQL逻辑查询语句执行顺序

    一 SELECT语句关键字的定义顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOI ...

  5. DAY10-MYSQL初识

    一 数据库管理软件的由来 基于我们之前所学,数据要想永久保存,都是保存于文件中,毫无疑问,一个文件仅仅只能存在于某一台机器上. 如果我们暂且忽略直接基于文件来存取数据的效率问题,并且假设程序所有的组件 ...

  6. Android指针管理:RefBase,SP,WP

    Android中通过引用计数来实现智能指针,并且实现有强指针与弱指针.由对象本身来提供引用计数器,但是对象不会去维护引用计数器的值,而是由智能指针来管理. 要达到所有对象都可用引用计数器实现智能指针管 ...

  7. 每天一道算法题目(18)——取等长有序数组的上中位数和不等长有序数组的第k小的数

    1.取上中位数 题目: 给定两个有序数组arr1和arr2,两个数组长度都为N,求两个数组中所有数的上中位数.要求:时间复杂度O(logN).      例如:          arr1 = {1, ...

  8. jQuery-图片的放大镜显示效果(需要大小图)

    1.default.aspx <%@ Page Language=.2em; height:.1em; text-align:center; font-size:128px;}    .zxx_ ...

  9. CSS制作水平垂直居中对齐 多种方式各有千秋

    作为前端攻城师,在制作Web页面时都有碰到CSS制作水平垂直居中,我想大家都有研究过或者写过,特别的其中的垂直居中,更是让人烦恼.这段时间,我收 集了几种不同的方式制作垂直居中方法,但每种方法各有千秋 ...

  10. MyBatis总结二:增删改查

    上一篇讲述了MyBatis的快速入门,下面在此基础上进行增删改查的操作: 首先定义dao层的接口: package com.zy.dao; import com.zy.domain.User; imp ...