POJ1052 Plato's Blocks
题目来源: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的更多相关文章
- POJ 1052 Plato's Blocks
		
Plato's Blocks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 734 Accepted: 296 De ...
 - POJ题目排序的Java程序
		
POJ 排序的思想就是根据选取范围的题目的totalSubmittedNumber和totalAcceptedNumber计算一个avgAcceptRate. 每一道题都有一个value,value ...
 - POJ题目细究
		
acm之pku题目分类 对ACM有兴趣的同学们可以看看 DP: 1011 NTA 简单题 1013 Great Equipment 简单题 102 ...
 - 【转】POJ百道水题列表
		
以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...
 - 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM
		
刚过去的周五(3-14)例行地主持了技术会议,主题正好是<UI层的设计模式——从Script.Code Behind到MVC.MVP.MVVM>,是前一天晚上才定的,中午花了半小时准备了下 ...
 - 【POJ-1390】Blocks      区间DP
		
Blocks Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5252 Accepted: 2165 Descriptio ...
 - 开发该选择Blocks还是Delegates
		
前文:网络上找了很多关于delegation和block的使用场景,发现没有很满意的解释,后来无意中在stablekernel找到了这篇文章,文中作者不仅仅是给出了解决方案,更值得我们深思的是作者独特 ...
 - poj 1390 Blocks
		
poj 1390 Blocks 题意 一排带有颜色的砖块,每一个可以消除相同颜色的砖块,,每一次可以到块数k的平方分数.问怎么消能使分数最大.. 题解 此题在徐源盛<对一类动态规划问题的研究&g ...
 - Java 同步代码块 - Synchronized Blocks
		
java锁实现原理: http://blog.csdn.net/endlu/article/details/51249156 The synchronized keyword can be used ...
 
随机推荐
- java 多线程系列---JUC原子类(四)之AtomicReference原子类
			
AtomicReference介绍和函数列表 AtomicReference是作用是对"对象"进行原子操作. AtomicReference函数列表 // 使用 null 初始 ...
 - 类型:Ajax;问题:ajax调用ashx参数获取不到;结果:ashx文件获取$.ajax()方法发送的数据
			
ashx文件获取$.ajax()方法发送的数据 今天在使用Jquery的ajax方法发送请求时,发现在后台中使用ashx文件无法接收到ajax方法中传递的参数,上网查了一下原因后发现了问题所在,原来是 ...
 - 问题:C#根据生日计算属相;结果:C#实现根据年份计算生肖属相的方法
			
这篇文章主要介绍了C#实现根据年份计算生肖属相的方法,涉及C#数组与字符串的操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了C#实现根据年份计算生肖属相的方法.分享给大家供大家 ...
 - UIBezierPath和CAShapeLayer配合肆意画图
			
一.CAShapeLayer CAShapeLayer 是 CALayer 的子类,但是比 CALayer 更灵活,可以画出各种图形 使用CAShapeLayer 绘制一个矩形 let layer ...
 - xcode减小静态库的大小(转)
			
减小静态库的大小 编译生成的.a文件太大,但又没有冗余的文件可以删除已减少体积,找了很久才找到解决办法,如下: Build Settings-->Generate Debug Symbols 将 ...
 - SharedPreferences 用法
			
private void getUserInfoFromPref(){ /* * 保存到文件的方法 * * Constant.user = (User)Constant.readObjectFromF ...
 - CheckBoxJS选中与反选得到Value
			
function XuanZe(val) { datastr = $("#hid_AID").val(); var newstr = ""; ...
 - 定位程序问题出现的原因工具-jstack
			
jstack还可以生成线程快照 如何使用jstack: 1.打开命令行,输入jstack 在任务管理器中就可看到对应进程id 2.在命令行中输入 jstack -l 进程id 这样就可得到进程中所有的 ...
 - 关于service和线程的区别
			
主要有两方面,访问控制和功能区别 首先,service是运行在主线程上的,并不是一个新的线程 其次,service在运行的时候可以被多个activity访问和控制,而线程是不可以的 最后,servic ...
 - day35-hibernate映射 05-Hibernate的一级缓存:快照区
			
SessionImpl里面有很多的Java集合,很多java集合才构成了一级缓存.一级缓存里面有一个非常特殊的区域叫做快照区.SessionImpl实现了Session接口,有很多Java集合(包括M ...