/*
【题目来源】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 框架堆叠的更多相关文章

  1. POJ 1128 Frame Stacking(拓扑排序&#183;打印字典序)

    题意  给你一些矩形框堆叠后的鸟瞰图  推断这些矩形框的堆叠顺序  每一个矩形框满足每边都至少有一个点可见  输入保证至少有一个解 按字典序输出全部可行解 和上一题有点像  仅仅是这个要打印全部的可行 ...

  2. Frame Stacking(拓扑排序)

    题目链接:http://acm.tju.edu.cn/toj/showp1076.html1076.   Frame Stacking Time Limit: 1.0 Seconds   Memory ...

  3. Frame Stacking ZOJ 1083,poj 1128

    Frame Stacking Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4034   Accepted: 1352 De ...

  4. 我给女朋友讲编程html系列(3) --html中的超链接标签-a标签 和 框架frame与框架集frameset

    我们浏览网页的时候,当单击某段文字或图片时,就会打开一个新的网页,这里面就使用了超链接. 就比如下图是一个导航类网页,当你单击某个链接就会打开新的网页. 比如,我拿我的qq空间“金河访谈”举例,新建一 ...

  5. POJ 1128 Frame Stacking (拓扑排序)

    题目链接 Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ ...

  6. POJ1128 Frame Stacking(拓扑排序+dfs)题解

    Description Consider the following 5 picture frames placed on an 9 x 8 array.  ........ ........ ... ...

  7. Frame Stacking 拓扑排序 图论

    Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ .... ...

  8. Frame Stacking

    poj1128:http://poj.org/problem?id=1128 题意:一个二维图里面有几个相框(四条边的空心矩形框).有重叠,求重叠顺序.还有题目保证至少存在一种符合要求的序列,当有多种 ...

  9. zoj 1083 Frame Stacking

    其实就是一个拓补排序.(动态记录第i个之上的j存不存在,反过来就是第j个之下的i) 首先确立每个框的位置(题目明确说了每一边都不会被完全覆盖)./*可以通过搜索,搜索到该框的所有四个角*/||如果题目 ...

随机推荐

  1. C语言基础知识--位运算

    1.原码,反码,补码: (1)在n位的机器数中,最高位为符号位,该位为零表示为正,为一表示为负:其余n-1位为数值位,各位的值可为零或一.当真值为正时,原码.反码.补码数值位 完全相同:当真值为负时, ...

  2. leetcode@ [336] Palindrome Pairs (HashMap)

    https://leetcode.com/problems/palindrome-pairs/ Given a list of unique words. Find all pairs of dist ...

  3. linux内核地址mapping

    linux内核采用页式存储管理,虚拟地址空间划分成固定大小的页面,由MMU(memory manager unit)在运行时将virtual address mapping to (或者说是变化成)某 ...

  4. Spark RDD概念学习系列之Spark的算子的作用(十四)

    Spark的算子的作用 首先,关于spark算子的分类,详细见 http://www.cnblogs.com/zlslch/p/5723857.html 1.Transformation 变换/转换算 ...

  5. this指针和m_hWnd的区别

    m_hWnd ① m_hWnd这个成员变量,最早是定义在类CWnd中,而且是类CWnd的第一个数据成员, 先看一下MSDN的解析: The handle of the Windows window a ...

  6. Linux下移植pjsip,使用QT开发

    1.移植pjsip env:fedora14 arm-linuc-gcc:gcc version 4.5.1 (ctng-1.8.1-FA) #./configure \ CC=arm-linux-g ...

  7. jquery页面加载的时候加载函数

    http://blog.csdn.net/tjcyjd/article/details/6713474 jQuery 页面加载初始化的方法有3种 ,页面在加载的时候都会执行脚本,应该没什么区别,主要看 ...

  8. type=INNODB和engine=INNODB的区别

    我在网站下载了一份源码,学习中, 发现type=INNODB,这个数据库引擎老实出错,,后来才一查资料才是: 在MYSQL5.5及以后版本中type=InnoDB 由ENGINE=InnoDB 代替. ...

  9. rqnoj-390-地震了!-动态规划

    一步步的往前走,判断当前状态与上一个状态的关闭. 注意,题目输入的楼层的速度是从小到大,而实际运用的楼层顺序是从大到小.. #include<stdio.h> #include<al ...

  10. contiki makefile框架分析 < contiki学习之一 >

    在linux下的工程编译,基本都可以使用makefile这个工具来完成.Contiki OS亦如此,下面分析contiki整个Makefile的框架,对makefile的具体内容暂不做分析.本文依赖于 ...