POJ1128 Frame Stacking 【拓扑排序】+【深搜】

Frame Stacking

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 4074   Accepted: 1371

Description

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

........ ........ ........ ........ .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

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.

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

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).

Sample Input

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

Sample Output

EDABC

两个月前做了一半就做不下去然后扔掉了的题,今天给它重新捡了起来,总算是A掉了,综合了构图、拓扑和回溯,算是很经典的题了。

题意:每张图片上面画了一些边框,给出这些边框叠在一起后的图片,求从下往上的重叠顺序,如果有多种结果的话就按照字典序输出所有结果。

题解:先构图,可以用边框的左上和右下坐标表示一个边框,若能确定A框在B框上面,那么map[B][A] = 1; ++in[A];至此,构图完成,然后就是拓扑输出序列了,这里有些难度,需要用到回溯,先选定当前入度为0的边框,将它放入ans数组,然后该边框标记为已用,并将所有与它联通的边框入度减一,再继续搜索ans数组下一位置,然后就该回溯了,将当前边框标记为未用,并将所有与它联通的边框入度+1,至此DFS完成。

#include <stdio.h>
#include <string.h>
#define maxn 32
#define maxm 28

char ori[maxn][maxn], ans[maxm];
int m, n, in[maxm], total;
bool map[maxm][maxm];
struct Node{
	int x, y;
} lt[maxm]; //leftButtom
struct Node2{
	int x, y;
} rb[maxm]; //rightTop

void getMap()
{
	int i, j, t, k, x, y;
	memset(map, 0, sizeof(map));
	memset(in, -1, sizeof(in));
	memset(lt, 0x3f, sizeof(lt));
	memset(rb, -1, sizeof(rb));
	for(i = total = 0; i < n; ++i)
		for(j = 0; j < m; ++j){
			if(ori[i][j] == '.') continue;
			t = ori[i][j] - 'A';
			if(in[t] == -1){
				in[t] = 0; //indicate t exist
				++total;
			}
			if(i < lt[t].x) lt[t].x = i;
			if(i > rb[t].x) rb[t].x = i;
			if(lt[t].y > j) lt[t].y = j;
			if(rb[t].y < j) rb[t].y = j;
		}
	for(i = 0; i < maxm; ++i){
		if(in[i] == -1) continue;
		for(x = lt[i].x; x <= rb[i].x; ++x)
			for(y = lt[i].y; y <= rb[i].y; ++y){
				if(x > lt[i].x && y > lt[i].y && x < rb[i].x && y < rb[i].y)
					continue;
				t = ori[x][y] - 'A';
				if(t != i && !map[i][t]){
					map[i][t] = true;
					++in[t];
				}
			}
	}
}

void DFS(int id) //fantastic!
{
	if(id == total){
		ans[id] = '\0';
		puts(ans); return;
	}
	for(int i = 0; i < maxm; ++i){
		if(in[i] == 0){
			ans[id] = 'A' + i;
			in[i] = -1;
			for(int j = 0; j < maxm; ++j)
				if(map[i][j]) --in[j];
			DFS(id + 1);
			in[i] = 0;
			for(int j = 0; j < maxm; ++j)
				if(map[i][j]) ++in[j];
		}
	}
}

int main()
{
	int i;
	while(scanf("%d%d", &n, &m) == 2){
		for(i = 0; i < n; ++i)
			scanf("%s", ori[i]);
		getMap();
		DFS(0);
	}
	return 0;
}

POJ1128 Frame Stacking 【拓扑排序】+【深搜】

时间: 2024-12-18 20:37:49

POJ1128 Frame Stacking 【拓扑排序】+【深搜】的相关文章

POJ 1128 &amp; ZOJ 1083 Frame Stacking (拓扑排序)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=83 http://poj.org/problem?id=1128 Frame Stacking Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4102   Accepted: 1378 Description Consider the following 5 picture frames placed

POJ1128 Frame Stacking(拓扑排序)经典

Frame Stacking Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4454   Accepted: 1509 Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ ........ ........ .CCC.... EEEEEE.. ........ ........ ..

UVA 124 &amp; POJ 1270 Following Orders(拓扑排序)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=60 http://poj.org/problem?id=1270 Following Orders Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3806   Accepted: 1507 Description Or

hdu 1258(深搜)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1258 Sum It Up Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4012    Accepted Submission(s): 2066 Problem Description Given a specified total t

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

题意  给你一些矩形框堆叠后的鸟瞰图  推断这些矩形框的堆叠顺序  每一个矩形框满足每边都至少有一个点可见  输入保证至少有一个解 按字典序输出全部可行解 和上一题有点像  仅仅是这个要打印全部的可行方案  建图还是类似  由于每一个矩形框的四边都有点可见  所以每一个矩形框的左上角和右下角的坐标是能够确定的  然后一个矩形框上有其他字符时  就让这个矩形框相应的字符和那个其他字符建立一个小于关系  由于要打印方案  所以在有多个入度为0的点时须要用DFS对每种选择都进行一遍拓扑排序 #incl

Frame Stacking(拓扑排序)

题目链接: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 anot

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

题意  给你一些矩形框堆叠后的俯视图  判断这些矩形框的堆叠顺序  每个矩形框满足每边都至少有一个点可见  输入保证至少有一个解 按字典序输出所有可行解 和上一题有点像  只是这个要打印所有的可行方案  建图还是类似  因为每个矩形框的四边都有点可见  所以每个矩形框的左上角和右下角的坐标是可以确定的  然后一个矩形框上有其它字符时  就让这个矩形框对应的字符和那个其它字符建立一个小于关系  由于要打印方案  所以在有多个入度为0的点时需要用DFS对每种选择都进行一遍拓扑排序 #include

POJ1094 Sorting It All Out 拓扑排序(深搜)

题意:给定n和m,n表示大写字母的前n个,m表示m个关系对,求能否确定唯一排序. 分析:分三种情况 (1)当输入完当前的关系对之后,已经能确定矛盾(不需要完全输入m个关系对时) eg. 3 3       A<B       B<A         B<C       当输入到第二对已经能判断矛盾,此时记下当前的所需要用到的关系对数ans=2:       接着输入,但是后面的关系对不作处理 (2) 当输入完当前的关系对之后,已经能确定唯一排序(不需要完全输入m个关系对,    但是必须

ACM/ICPC 之 拓扑排序+DFS(POJ1128(ZOJ1083))

经典的拓扑排序问题,难点在于字典序输出和建立拓扑图,另外理解题意是最难的难点,没有之一... POJ1128(ZOJ1083)-Frame Stacking 题意:每个图片由同一字母组成的边框表示,每个图片的字母都不同: 在一个最多30*30的区域放置这些图片,问底层向顶层叠加的图片次序,多选时按字典序输出 注:每个图片的四边都会有字符显示,其中顶点显示两边. 题解:题意的理解是难点,题目对图片的范围确定说得有点含糊不清,博主一开始就被出现的五张图片的样例迷惑,理解重心放错了.题目最需要理解的是