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) 首先确立每个框的位置(题目明确说了每一边都不会被完全覆盖)./*可以通过搜索,搜索到该框的所有四个角*/||如果题目 ...
随机推荐
- 使用 CreateInstallMedia 创建 苹果系统安装U盘
一般来说,从app store上面 下载下来的image位置,都是在 /Applications 下面 使用命令创建安装U盘,(备份一下命令,太长,记不住) sudo /Applications/In ...
- 链表逆序(JAVA实现)
题目:将一个有链表头的单向单链表逆序 分析: 链表为空或只有一个元素直接返回: 设置两个前后相邻的指针p,q,使得p指向的节点为q指向的节点的后继: 重复步骤2,直到q为空: 调整链表头和链表尾: 图 ...
- WINRAR评估版本弹出框消除
网上有很多WINRAR评估版本,这些版本下载安装了之后总会有些广告弹出,让人很烦恼,现在教大家一个方法消除这些弹出框. 复制以下代码: RAR registration data SeVeN U ...
- HDU 5665 Lucky (水题)
Lucky 题目链接: http://acm.hust.edu.cn/vjudge/contest/123316#problem/G Description Chaos August likes to ...
- Contest 7.23(不知道算什么)
Problem A URAL 1181 Cutting a Painted Polygon 题目大意就是说有一个N边形,让你做N-3条边,让他们的每个三角形的三个顶点颜色都不相同. 这里有一个引理 ...
- HDU/杭电2013多校第三场解题报告
今天悲剧了,各种被虐啊,还是太年轻了 Crime 这道题目给的时间好长,第一次就想到了暴力,结果华丽丽的TLE了. 后来找了一下,发现前24个是1, 2, 6, 12, 72, 72, 864, 17 ...
- mac 下对 iterm 终端 设置代理
vi .profile export http_prox="http://xxxx:port" export https_proxy="http://xxxx:port& ...
- SQL Delta实用案例介绍 (对应软件)
http://blog.csdn.net/hongdi/article/details/5363209
- php redis安装
一.redis安装 1 下载redis安装包 wget http://redis.googlecode.com/files/redis-2.4.17.tar.gz (若无法下载请手动下载) 2 编译安 ...
- 【VxWorks系列】任务间同步与通信之共享内存
在开始之前先说明三个概念,任务间的同步,互斥,通信. 同步,是指一个任务等待某个条件发生,而另外一个任务引发这个条件后,等待的任务会被触发执行相应的处理.这就是一个任务与另一任务之间的同步控制. 互斥 ...