Frame Stacking 拓扑排序 图论
Description
........ ........ ........ ........ .CCC....
EEEEEE.. ........ ........ ..BBBB.. .C.C....
E....E.. DDDDDD.. ........ ..B..B.. .C.C....
E....E.. D....D.. ........ ..B..B.. .CCC....
E....E.. D....D.. ....AAAA ..B..B.. ........
E....E.. D....D.. ....A..A ..BBBB.. ........
E....E.. DDDDDD.. ....A..A ........ ........
E....E.. ........ ....AAAA ........ ........
EEEEEE.. ........ ........ ........ ........
1 2 3 4 5
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.
.CCC....
ECBCBB..
DCBCDB..
DCCC.B..
D.B.ABAA
D.BBBB.A
DDDDAD.A
E...AAAA
EEEEEE..
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
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
Sample Input
9
8
.CCC....
ECBCBB..
DCBCDB..
DCCC.B..
D.B.ABAA
D.BBBB.A
DDDDAD.A
E...AAAA
EEEEEE..
Sample Output
EDABC
Source
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<deque>
#include<iomanip>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<fstream>
#include<memory>
#include<list>
#include<string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN 35
#define N 33
#define MOD 10000007
#define INF 1000000009
const double eps = 1e-;
const double PI = acos(-1.0);
/*
1 遍历一遍图 记录四个顶点位置
2 把边框遍历一遍,如果被覆盖就 在图中加一条边(如B被C覆盖,加一条B->C) B必须在C之前放好
3 DFS 输出所有解
*/
struct node
{
int u, d, l, r;
node()
{
u = l = INF; d = r = -INF;
}
};
bool vis[MAXN];
int n, m, cnt;//n行m列 有cnt个字母
vector<int> E[MAXN];
int in[MAXN];//保存每个点的入度
node pos[MAXN];//每个字母四条边框
char g[MAXN][MAXN];
void dfs(int k, char ans[])
{
if (k == cnt)
{
ans[k] = '\0';
printf("%s\n", ans);
return;
}
for (int i = ; i < MAXN; i++)
{
if (pos[i].l == INF) continue;
if (!vis[i] && in[i] == )
{
vis[i] = true;
for (int j = ; j < E[i].size(); j++)
in[E[i][j]]--;
ans[k] = 'A' + i;
dfs(k + , ans);
vis[i] = false;
for (int j = ; j < E[i].size(); j++)
in[E[i][j]]++;
}
}
}
int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
memset(vis, , sizeof(vis));
memset(in, , sizeof(in));
cnt = ;
for (int i = ; i < MAXN; i++)
{
E[i].clear();
pos[i].u = pos[i].l = INF, pos[i].d = pos[i].r = -INF;
}
for (int i = ; i < n; i++)
{
scanf("%s", g[i]);
for (int j = ; j < m; j++)
{
if (g[i][j] == '.') continue;
pos[g[i][j] - 'A'].l = min(pos[g[i][j] - 'A'].l, j);
pos[g[i][j] - 'A'].r = max(pos[g[i][j] - 'A'].r, j);
pos[g[i][j] - 'A'].u = min(pos[g[i][j] - 'A'].u, i);
pos[g[i][j] - 'A'].d = max(pos[g[i][j] - 'A'].d, i);
}
}
for (int i = ; i<; i++)
if (pos[i].r != INF)
{
memset(vis, false, sizeof(vis));
for (int j = pos[i].l; j <= pos[i].r; j++)
{
if (!vis[g[pos[i].u][j] - 'A'] && g[pos[i].u][j] != 'A' + i)
{
vis[g[pos[i].u][j] - 'A'] = true;
E[i].push_back(g[pos[i].u][j] - 'A');
in[g[pos[i].u][j] - 'A']++;
}
}
for (int j = pos[i].l; j <= pos[i].r; j++)
{
if (!vis[g[pos[i].d][j] - 'A'] && g[pos[i].d][j] != 'A' + i)
{
vis[g[pos[i].d][j] - 'A'] = true;
E[i].push_back(g[pos[i].d][j] - 'A');
in[g[pos[i].d][j] - 'A']++;
}
}
for (int j = pos[i].u; j <= pos[i].d; j++)
{
if (!vis[g[j][pos[i].l] - 'A'] && g[j][pos[i].l] != 'A' + i)
{
vis[g[j][pos[i].l] - 'A'] = true;
E[i].push_back(g[j][pos[i].l] - 'A');
in[g[j][pos[i].l] - 'A']++;
}
} for (int j = pos[i].u; j <= pos[i].d; j++)
{
if (!vis[g[j][pos[i].r] - 'A'] && g[j][pos[i].r] != 'A' + i)
{
vis[g[j][pos[i].r] - 'A'] = true;
E[i].push_back(g[j][pos[i].r] - 'A');
in[g[j][pos[i].r] - 'A']++;
}
}
}
for (int i = ; i < ; i++)
if (pos[i].l != INF)
cnt++;
memset(vis, false, sizeof(vis));
char s[MAXN];
dfs(, s);
} }
Frame Stacking 拓扑排序 图论的更多相关文章
- POJ 1128 Frame Stacking (拓扑排序)
题目链接 Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ ...
- POJ 1128 Frame Stacking 拓扑排序+暴搜
这道题输出特别坑.... 题目的意思也不太好理解.. 就解释一下输出吧.. 它让你 从下往上输出. 如果有多种情况,按照字典序从小往大输出... 就是这个多种情况是怎么产生的呢. 下面给一组样例. 很 ...
- CSU 1804: 有向无环图 拓扑排序 图论
1804: 有向无环图 Submit Page Summary Time Limit: 5 Sec Memory Limit: 128 Mb Submitted: 716 ...
- python 排序 拓扑排序
在计算机科学领域中,有向图的拓扑排序是其顶点的先行排序,对于每个从顶点u到顶点v的有向边uv,在排序的结果中u都在v之前. 如果图是有向无环图,则拓扑排序是可能的(为什么不说一定呢?) 任何DAG具有 ...
- 图论之拓扑排序 poj1128 Frame Stacking
题目网址 http://poj.org/problem?id=1128 思路:遍历找出每一种字母出现的最大和最小的横纵坐标,假如本应出现字母A的地方出现了字母B,那么A一定在字母B之前,这就相当于点A ...
- Frame Stacking(拓扑排序)
题目链接:http://acm.tju.edu.cn/toj/showp1076.html1076. Frame Stacking Time Limit: 1.0 Seconds Memory ...
- POJ 1128 Frame Stacking(拓扑排序·打印字典序)
题意 给你一些矩形框堆叠后的鸟瞰图 推断这些矩形框的堆叠顺序 每一个矩形框满足每边都至少有一个点可见 输入保证至少有一个解 按字典序输出全部可行解 和上一题有点像 仅仅是这个要打印全部的可行 ...
- POJ1128 Frame Stacking(拓扑排序+dfs)题解
Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ ... ...
- POJ1128 Frame Stacking(拓扑排序)
题目链接:http://poj.org/problem?id=1128 题意:给你一个平面,里面有些矩形(由字母围成),这些矩形互相有覆盖关系,请从求出最底层的矩形到最上层的矩形的序列,如果存在多种序 ...
随机推荐
- Spring.Net学习笔记(7)-事务
一.开发环境 操作系统:Win7 编译器:VS2010 二.涉及程序集 Spring.Core.dll Spring.Data.dll Common.Logging.dll 三.开发过程 1.项目结构 ...
- 动态属性ExpandoObject
1.动态创建对象及其属性ExpandoObject 查看ExpandoObject的定义:
- Framework7首页隐藏navbar
f7首页隐藏navbar其他页面显示navbar 帮别人解决问题,自己也记录一下, 首页.navbar加.navbar-hidden, 首页.page加.no-navbar, 如果首页有.navbar ...
- 实例化Class类的5种方式
Java的数据类型可以分为两类,即引用类型和原始类型.对于每种类型的对象,Java虚拟机会实例化不可变的java.lang. Class对象.它提供了在运行时检查对象属性的方法,这些属性包括它的成员和 ...
- JavaScript中逻辑运算符的使用
逻辑运算符用于对一个或多个布尔值进行逻辑运算.在JavaScript中有3个逻辑运算符,如下表所示. 运算符 描述 示例 && 逻辑与 a && b //当a和b都为 ...
- Android 网络图片查看器与网页源码查看器
在AndroidManifest.xml里面先添加访问网络的权限: <uses-permission android:name="android.permission.INTERNET ...
- 生成Nuget 源代码包来重用你的Asp.net MVC代码
ASP.NET 开发人员有时会陷入一种困境:想要重用以前写过的东西,如一些具有完整功能的Web页面+后台逻辑, 往往不那么直接了当,因此很不爽.经常采用的方式是:找到以前写过的项目,从中挑出来一些有用 ...
- Python安装笔记
1.教程
- Context Switches msdn
Context Switches https://msdn.microsoft.com/en-us/library/ms682105(VS.85).aspx The scheduler mainta ...
- 音视频】5.ffmpeg命令分类与使用
GT其实平时也有一些处理音视频的个人或者亲人需求,熟练使用ffmpeg之后也不要借助图示化软件,一个命令基本可以搞定 G: 熟练使用ffmpeg命令!T :不要死记硬背,看一遍,自己找下规律,敲一遍, ...