题目链接:http://acm.tju.edu.cn/toj/showp1076.html1076.   Frame Stacking


Time Limit: 1.0 Seconds   Memory Limit: 65536K
Total Runs: 145   Accepted Runs: 54

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

Now place them on top of one another starting with 1 at the bottom and ending up with 5 on top. If any part of a frame covers another it hides that part of the frame below.

Viewing the stack of 5 frames we see the following.

In what order are the frames stacked from bottom to top? The answer is EDABC.

Your problem is to determine the order in which the frames are stacked from
bottom to top given a picture of the stacked frames. Here are the rules:

1. The width of the frame is always exactly 1 character and the sides are never
shorter than 3 characters.

2. It is possible to see at least one part of each of the four sides of a frame.
A corner shows two sides.

3. The frames will be lettered with capital letters, and no two frames will
be assigned the same letter.

INPUT DATA

Each input block contains the height, h (h≤30) on the first line and the
width w (w≤30) on the second. A picture of the stacked frames is then given
as h strings with w characters each.

Example input:

9
8
.CCC....
ECBCBB..
DCBCDB..
DCCC.B..
D.B.ABAA
D.BBBB.A
DDDDAD.A
E...AAAA
EEEEEE..

Your input may contain multiple blocks of the format described above, without any blank lines in between. All blocks in the input must be processed sequentially.

OUTPUT DATA

Write the solution to the standard output. Give the letters of the frames in
the order they were stacked from bottom to top. If there are multiple possibilities
for an ordering, list all such possibilities in alphabetical order, each one
on a separate line. There will always be at least one legal ordering for each
input block. List the output for all blocks in the input sequentially, without
any blank lines (not even between blocks).

Example Output:

EDABC
题目大意:给定一个摞起来的照片图片,输出照片排放的位置,如果有多种放法的话按字典序从小到大输出所有的解
题解,这是一个很好的拓扑排序的题,题目中说了每个相片的每条边肯定会漏出至少一个字母,所以很容易确定每个相片的位置,及找到这个相片的横坐标和纵坐标的最左端和最右端,最上端,最下端的值
在处理的时候不要忘记对'.'的处理,还有从A~Z不是每个字母都会出现。
建图的时候因为这个图有很多的重边,而且边数不多的时候最好用矩阵存储,在拓扑排序的时候因为是要输出所有的解,所以使用dfs最好。
下面代码中有详细的注释
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define N 110
#define INF 0x1fffffff struct Node{
int x1,y1,x2,y2;//x1,y1是最下和最左的点
bool flag;//标记一个字母是否出现过
void init(){//初始化所有点的时候找最大的时候初始化成最小,找最小的时候初始化成最大,才可以不断更新
flag = ;
x1 = y1 = INF;
x2 = y2 = -INF;
}
}node[];
int n , m;
char mp[N][N];//保存一张图
int g[][];//建立关系图
int in[];//入度
int vis[];//是否访问过
void add(int u , int v)
{
g[u][v]=;
}
int total;
void dfs(int cnt , string s)
{
if(cnt==total) printf("%s\n",s.c_str());//dfs当已经把所有的字母顺序都访问过了后就不再进行搜索了
for(int i= ;i < ;i++)
{
if(node[i].flag == &&!vis[i]&&in[i]==)//注意考虑这个字母没有出现的第一个条件
{
vis[i]=;
for(int j = ; j < ; j++)
if(g[i][j]) in[j]--;
char ch = i+'A';
dfs(cnt+,s+ch);//因为找所有解所以后面要还原之前操作
for(int j = ; j < ;j++)
if(g[i][j]) in[j]++;
vis[i]=;
}
}
} void tuop()//拓扑排序
{
total = ;
for(int i = ;i < ; i++)
vis[i] = ,in[i] = ;
for(int i = ; i < ;i++)
for(int j = ;j < ;j++)
if(g[i][j]) in[j]++;
for(int i = ;i < ;i++)
total +=node[i].flag;
dfs(,"");
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i = ;i < n ; i++)
scanf("%s",mp[i]);//如果挨个读入字符两重循环scanf会读入末尾的空行
for(int i = ; i < ; i++)
node[i].init();
for(int i = ;i < n ;i++)
{
for(int j = ; j < m ;j++)
{
if(mp[i][j]=='.') continue;
int id = mp[i][j]-'A';
node[id].flag=;
node[id].x1 = min(node[id].x1,i);
node[id].y1 = min(node[id].y1,j);
node[id].x2 = max(node[id].x2,i);
node[id].y2 = max(node[id].y2,j);
}
}//找到每个字母对应的照片的位置
memset(g,,sizeof(g));
for(int i = ;i < ;i++)
{
if(node[i].flag == ) continue;
int y1 = node[i].y1 , y2 = node[i].y2,x;
for(x = node[i].x1;x<=node[i].x2 ;x++)
{
if(mp[x][y1]!=i+'A') add(i,mp[x][y1]-'A');
if(mp[x][y2]!=i+'A') add(i,mp[x][y2]-'A');
}
int x1 = node[i].x1 , x2 = node[i].x2,y;
for(y = node[i].y1;y<=node[i].y2 ;y++)
{
if(mp[x1][y]!=i+'A') add(i,mp[x1][y]-'A');
if(mp[x2][y]!=i+'A') add(i,mp[x2][y]-'A');
}
}//扫描每条边并建图,如图这条边上本来应该出现同一个字母的时候出现了其他的就说明了其他的字母在这个字母的照片的上面所以建一条从下面字母到上面字母的有向边
tuop();
}
return ;
}
 

Frame Stacking(拓扑排序)的更多相关文章

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

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

  2. Frame Stacking 拓扑排序 图论

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

  3. POJ 1128 Frame Stacking 拓扑排序+暴搜

    这道题输出特别坑.... 题目的意思也不太好理解.. 就解释一下输出吧.. 它让你 从下往上输出. 如果有多种情况,按照字典序从小往大输出... 就是这个多种情况是怎么产生的呢. 下面给一组样例. 很 ...

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

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

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

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

  6. POJ1128 Frame Stacking(拓扑排序)

    题目链接:http://poj.org/problem?id=1128 题意:给你一个平面,里面有些矩形(由字母围成),这些矩形互相有覆盖关系,请从求出最底层的矩形到最上层的矩形的序列,如果存在多种序 ...

  7. 图论之拓扑排序 poj1128 Frame Stacking

    题目网址 http://poj.org/problem?id=1128 思路:遍历找出每一种字母出现的最大和最小的横纵坐标,假如本应出现字母A的地方出现了字母B,那么A一定在字母B之前,这就相当于点A ...

  8. USACO4.4 Frame Up【拓扑排序】

    题意居然还读了好久... 读完题目之后大概就知道拓扑排序了.用拓扑可以求出一些字母之间的关系,谁先,谁后.但是这个关系不是唯一确定的,所以就会产生多种方案(题目还要求按字典序输出所有的方案) 输出方案 ...

  9. ACM/ICPC 之 拓扑排序+DFS(POJ1128(ZOJ1083)-POJ1270)

    两道经典的同类型拓扑排序+DFS问题,第二题较第一题简单,其中的难点在于字典序输出+建立单向无环图,另外理解题意是最难的难点,没有之一... POJ1128(ZOJ1083)-Frame Stacki ...

随机推荐

  1. Win10关闭某程序的通知的方法

    一.点击右下角的通知图标. 二.点击所有通知. 三.点击系统 四.点击通知和操作 五.下拉,看到:获取来自这些发送者的通知 六.关闭自己想关闭通知的程序即可.

  2. C++ 头文件系列(iostream)

    1. 简介 这个头文件非常特殊,它只声明了8个常用流对象. 2. 8个对象 2.1 窄字符对象(char) extern istream cin extern ostream cout extern ...

  3. [置顶] xamarin android自定义标题栏(自定义属性、回调事件)

    自定义控件的基本要求 这篇文章就当是自定义控件入门,看了几篇android关于自定义控件的文章,了解了一下,android自定义控件主要有3种方式: 自绘控件:继承View类,所展示的内容在OnDra ...

  4. ArcGIS 网络分析[2.4] OD成本矩阵

    什么是OD成本矩阵? 先不说这个东西是什么,我们还是举一个实际的例子: 现在存在3个城市北京.上海.武汉,请分析他们两两之间的通行时间. 很简单嘛!北京到上海,北京到武汉,上海到武汉都来一次最短路径分 ...

  5. C#又能出来装个B了。一步一步微信跳一跳自动外挂

    PS:语言只是载体.思维逻辑才是王道 前天看见了个python的脚本.于是装python.配置环境变量.装pip.折腾了一上午,最终装逼失败. 于是进入博客园,顶部有篇文章吸引了我 .NET开发一个微 ...

  6. js回到顶部------转载

    [1]锚点 使用锚点链接是一种简单的返回顶部的功能实现.该实现主要在页面顶部放置一个指定名称的锚点链接,然后在页面下方放置一个返回到该锚点的链接,用户点击该链接即可返回到该锚点所在的顶部位置 [注意] ...

  7. Servlet与Jsp的结合使用实现信息管理系统一

    PS:1:先介绍一下什么是Servlet? Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交互式地 ...

  8. 在Ubuntu 12.04系统中安装配置OpenCV 2.4.3的方法

    在Ubuntu 12.04系统中安装配置OpenCV 2.4.3的方法   对于,在Linux系统下做图像识别,不像在windows下面我们可以利用Matlab中的图像工具箱来实现,我们必须借助Ope ...

  9. JavaScript的DOM编程--07--节点的属性

    节点的属性: 1). nodeName: 代表当前节点的名字. 只读属性. 如果给定节点是一个文本节点, nodeName 属性将返回内容为 #text 的字符串 2). nodeType:返回一个整 ...

  10. MySQL一对一:一对多:多对多: 实例!!!!

    学生表和课程表可以多对多 一个学生可以学多门课程 一门课程可以有多个学生: 多对多 *** 一个学生对应一个班级 一个班级对应多个学生: 一对多 *** 一个老师对应多个学生 多个学生对应一个老师:一 ...