Frame Stacking 框架堆叠
/*
【题目来源】http://poj.org/problem?id=1128 【题目分析】
几张图片叠在一起,给出堆叠后的情况,要求出所有可能的从下到上的堆叠顺序。 【思路分析】
1.题目已经很明确的告诉每个边框的每条边,至少会有一个字母露在外面
所以遍历整张图,确定每个边框的范围。 只需确定左上角和右下角即可。
2.根据每个边框的范围再遍历,若应该出现A的位置出现了B,那么B一定在A上面。这样各个边框的上下顺序就求出来。
若B在A上面,那么记录A->B。
3.拓扑排序
4.要求输出所有能情况且按字母顺序输出。那么只要按照字母顺序使用DFS(递归)来解决,注意处理完入度为0的点(删边更新入度)
递归进去后要还原回来(删去的边弄回来,入度更新回来)。从而保证可以下次使用 【小小心得】
参考了网上代码;拓扑排序的递归用法
*/
#include <iostream>
#include <cstring>
#include <iterator>
#include <vector>
#include <cstdio>
using namespace std; struct Frame
{
int x1, y1;//左上角 int x2, y2;//右下角 //左上角必须初始化大一点,右下角必须初始化小一点
Frame()
{
x1 = y1 = 100; x2 = y2 = -100;
}
}; //记录26个字母使用了哪些
bool used[26]; //入度
int into[26]; //存储拓扑排序的图
int map[26][26]; //输入的原始图
char matrix[32][32]; vector<char> ans; //建立拓扑排序的图 即更新into数组
void buildMap(Frame frame[])
{
for (int i = 0; i < 26; ++i)
{
//若此字母用过
if (used[i])
{
//遍历frame第一列和最后一列
for (int j = frame[i].x1; j <= frame[i].x2; ++j)
{
if (matrix[j][frame[i].y1] != i+'A')
{
//要加这个判断条件,不然入度会被多算 如CBBC 则B的入度被算成了2其实是1
if (map[i][matrix[j][frame[i].y1]-'A'] == 0)
{
//记录入度
into[matrix[j][frame[i].y1]-'A']++;
//建图
map[i][matrix[j][frame[i].y1]-'A'] = 1;
}
}
if (matrix[j][frame[i].y2] != i+'A')
{
if (map[i][matrix[j][frame[i].y2]-'A'] == 0)
{
into[matrix[j][frame[i].y2]-'A']++; map[i][matrix[j][frame[i].y2]-'A'] = 1;
}
}
}
//遍历frame第一行和最后一行
for (int j = frame[i].y1; j <= frame[i].y2; ++j)
{
if (matrix[frame[i].x1][j] != i+'A')
{
if (map[i][matrix[frame[i].x1][j]-'A'] == 0)
{
into[matrix[frame[i].x1][j]-'A']++; map[i][matrix[frame[i].x1][j]-'A'] = 1;
}
}
if (matrix[frame[i].x2][j] != i+'A')
{
if (map[i][matrix[frame[i].x2][j]-'A'] == 0)
{
into[matrix[frame[i].x2][j]-'A']++; map[i][matrix[frame[i].x2][j]-'A'] = 1;
}
}
}
}
}
} //depth用于判断递归了多少次
void topo(int depth, int count)
{
//若递归的次数大于或等于所用字母的次数则可以结束
if (depth >= count)
{
copy(ans.begin(), ans.end(), ostream_iterator<char>(cout)); cout << endl; return;
} for (int i = 0; i < 26; ++i)
{
if (used[i])
{
if (into[i] == 0)
{
//删除入度为0的点所发出的边
ans.push_back(i+'A'); into[i] = -1; for (int k = 0; k < 26; ++k)
{
if (map[i][k] == 1)
{
into[k]--;
}
} topo(depth+1, count); //还原
ans.pop_back(); into[i] = 0; for (int k = 0; k < 26; ++k)
{
if (map[i][k] == 1)
{
into[k]++;
}
}
}
}
}
} int main()
{
int n, m; while (scanf("%d",&n) != EOF)
{
cin >> m; memset(used, 0, sizeof(used)); memset(into, 0, sizeof(into)); memset(map, 0, sizeof(map)); memset(matrix, 0, sizeof(matrix)); Frame frame[26]; ans.clear(); string temp; for (int i = 0; i < n; ++i)
{
cin >> temp;
for (int j = 0; j < m; ++j)
{
matrix[i][j] = temp[j]; if (matrix[i][j] != '.')
{
int toNum = matrix[i][j]-'A'; used[toNum] = true;
//更新左上角和右下角
if (frame[toNum].x1 > i) frame[toNum].x1 = i;
if (frame[toNum].y1 > j) frame[toNum].y1 = j;
if (frame[toNum].x2 < i) frame[toNum].x2 = i;
if (frame[toNum].y2 < j) frame[toNum].y2 = j;
}
}
} buildMap(frame); //一共用了多少个字母
int count = 0; for (int i = 0; i < 26; ++i)
if (used[i])
count++; topo(0, count);
}
}
Frame Stacking 框架堆叠的更多相关文章
- POJ 1128 Frame Stacking(拓扑排序·打印字典序)
题意 给你一些矩形框堆叠后的鸟瞰图 推断这些矩形框的堆叠顺序 每一个矩形框满足每边都至少有一个点可见 输入保证至少有一个解 按字典序输出全部可行解 和上一题有点像 仅仅是这个要打印全部的可行 ...
- Frame Stacking(拓扑排序)
题目链接:http://acm.tju.edu.cn/toj/showp1076.html1076. Frame Stacking Time Limit: 1.0 Seconds Memory ...
- Frame Stacking ZOJ 1083,poj 1128
Frame Stacking Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4034 Accepted: 1352 De ...
- 我给女朋友讲编程html系列(3) --html中的超链接标签-a标签 和 框架frame与框架集frameset
我们浏览网页的时候,当单击某段文字或图片时,就会打开一个新的网页,这里面就使用了超链接. 就比如下图是一个导航类网页,当你单击某个链接就会打开新的网页. 比如,我拿我的qq空间“金河访谈”举例,新建一 ...
- POJ 1128 Frame Stacking (拓扑排序)
题目链接 Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ ...
- POJ1128 Frame Stacking(拓扑排序+dfs)题解
Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ ... ...
- Frame Stacking 拓扑排序 图论
Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ .... ...
- Frame Stacking
poj1128:http://poj.org/problem?id=1128 题意:一个二维图里面有几个相框(四条边的空心矩形框).有重叠,求重叠顺序.还有题目保证至少存在一种符合要求的序列,当有多种 ...
- zoj 1083 Frame Stacking
其实就是一个拓补排序.(动态记录第i个之上的j存不存在,反过来就是第j个之下的i) 首先确立每个框的位置(题目明确说了每一边都不会被完全覆盖)./*可以通过搜索,搜索到该框的所有四个角*/||如果题目 ...
随机推荐
- Linux内存中的Cache真的能被回收么?
在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个RHEL6的系统上,free命令的显示内容大概是这样一个状态: [root@tencent64 ~]# free ...
- homework08
1.局部变量生命周期 #include "iostream.h" ;} int main() { ; add1(n); cout << n << endl; ...
- OAuth 2.0介绍学习
OAuth2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0. OAuth 2.0关注客户端开发者的简易性.要么通过组织在资源拥有者和HTTP服务商之间的被批 ...
- URAL 2066 Simple Expression (水题,暴力)
题意:给定三个数,让你放上+-*三种符号,使得他们的值最小. 析:没什么好说的,全算一下就好.肯定用不到加,因为是非负数. 代码如下: #pragma comment(linker, "/S ...
- 从Jetty、Tomcat和Mina中提炼NIO构架网络服务器的经典模式(二)
本文转载自 http://blog.csdn.net/cutesource/article/details/6192145 下面再来看看Tomcat是如何使用NIO来构架Connector这块的. 先 ...
- .NET的Snk使用方法
保护你Asp.Net生成的DLL和Code不被别人反编译 大家做项目开发一般都是分层的,比如UI层,业务层,数据访问层.业务层引用数据访问层的DLL(比如 dataAccess.dll),并使用da ...
- SQLServer2008设置开启INTERNET远程连接
SQL Server 2008默认是不允许远程连接的,sa帐户默认禁用的,如果想要在本地用SSMS连接远程服务器上的SQL Server 2008,需要做两个部分的配置: 使用sa账户登录SQL Se ...
- TcxDBLookupCombobox 级联时第二级不显示正确内容的处理方法
在使用两个级联的 TcxDBLookupCombobox 时,会出现这种情况:当第一级的内容变更后,第二级的控件在界面上显示的文本不变化,即使数据集已经通过 Properites.OnChange 事 ...
- C#文件读写常用类介绍
首先要熟悉.NET中处理文件和文件夹的操作.File类和Directory类是其中最主要的两个类.了解它们将对后面功能的实现提供很大的便利. 本节先对和文件系统相关的两个.NET类进行简要介 ...
- Linux內核中常用的一些延時方法
Linux內核中常用的一些延時方法 這些方法在以下路徑下定義:kernel/include/linux/delay.h #ifndef _LINUX_DELAY_H #define _LINUX_DE ...