USACO 4.4.3 Frame Up 重叠的图像 题解与分析
2013-09-18 21:36
337 查看
Frame Up 重叠的图像
译 by Felicia Crazy
现在,把这些图像按照 1—5 的编号从下到上重叠,第 1 张在最下面,第 5 张在最顶端。如果一张图像覆盖了另外一张图像,那么底下的图像的一部分就变得不可见了。我们得到下面的图像:
对于这样一张图像,计算构成这张图像的矩形图像从底部到顶端堆叠的顺序。
下面是这道题目的规则:
矩形的边的宽度为 1 ,每条边的长度都不小于 3 。
矩形的每条边中,至少有一部分是可见的。注意,一个角同时属于两条边。
矩形用大写字母表示,并且每个矩形的表示符号都不相同。
INPUT FORMAT:
(file frameup.in)
第一行 两个用空格分开的整数:图像高 H (3 <= H <=30) 和图像宽 W (3 <= W <= 30) 。
第二行到第 H+1 行 H 行,每行 W 个字母。
OUTPUT FORMAT:
(file frameup.out)
按照自底向上的顺序输出字母。如果有不止一种情况,按照字典顺序输出每一种情况(至少会有一种合法的顺序)。
【评测信息】:
TASK: frameup
LANG: C++
Compiling...
Compile: OK
Executing...
Test 1: TEST OK [0.011 secs, 3524 KB]
Test 2: TEST OK [0.011 secs, 3524 KB]
Test 3: TEST OK [0.011 secs, 3524 KB]
Test 4: TEST OK [0.011 secs, 3524 KB]
Test 5: TEST OK [0.011 secs, 3524 KB]
Test 6: TEST OK [0.011 secs, 3524 KB]
Test 7: TEST OK [0.011 secs, 3524 KB]
Test 8: TEST OK [0.205 secs, 3656 KB]
Test 9: TEST OK [0.454 secs, 3920 KB]
All tests OK.
YOUR PROGRAM ('frameup') WORKED FIRST TIME!
That's fantastic-- and a rare thing. Please accept these special automatedcongratulations.
转载注明出处:http://blog.csdn.net/u011400953
译 by Felicia Crazy
描述
看下面的五张 9 x 8 的图像:........ ........ ........ ........ .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
现在,把这些图像按照 1—5 的编号从下到上重叠,第 1 张在最下面,第 5 张在最顶端。如果一张图像覆盖了另外一张图像,那么底下的图像的一部分就变得不可见了。我们得到下面的图像:
.CCC.... ECBCBB.. DCBCDB.. DCCC.B.. D.B.ABAA D.BBBB.A DDDDAD.A E...AAAA EEEEEE..
对于这样一张图像,计算构成这张图像的矩形图像从底部到顶端堆叠的顺序。
下面是这道题目的规则:
矩形的边的宽度为 1 ,每条边的长度都不小于 3 。
矩形的每条边中,至少有一部分是可见的。注意,一个角同时属于两条边。
矩形用大写字母表示,并且每个矩形的表示符号都不相同。
格式
PROGRAM NAME: frameupINPUT FORMAT:
(file frameup.in)
第一行 两个用空格分开的整数:图像高 H (3 <= H <=30) 和图像宽 W (3 <= W <= 30) 。
第二行到第 H+1 行 H 行,每行 W 个字母。
OUTPUT FORMAT:
(file frameup.out)
按照自底向上的顺序输出字母。如果有不止一种情况,按照字典顺序输出每一种情况(至少会有一种合法的顺序)。
SAMPLE INPUT
9 8 .CCC.... ECBCBB.. DCBCDB.. DCCC.B.. D.B.ABAA D.BBBB.A DDDDAD.A E...AAAA EEEEEE..
SAMPLE OUTPUT
EDABC
【分析】:
首先对于每种字符,会组成不同矩形,统计这些矩形的左上角<即最左值和最上值>,右上角<即最右值和最下值>,然后建图:若本来在该矩形的边上存在不同于该矩形的字符,则将该矩形和不同于该矩形的字符对应的矩形编号连一条有向边,然后跑一边拓扑排序,注意,不同的拓扑序可能造成答案不同,因此用DFS来枚举所有拓扑序而不仅仅只跑一遍,最后对答案排序,输出即可
【时间复杂度】:
设字符种类为kind,则建图过程复杂度为O(kind*H*W),统计入度O(kind*kind),拓扑排序O(kind*kind*kind)
【代码】:
/* ID:csyzcyj1 PROG:frameup LANG:C++ */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> #include<iostream> #include<vector> #include<stack> #include<queue> #include<map> using namespace std; #define MAX 31 #define MAXN 101 #define IMAX 21474836 struct rectangle { int l,r,u,d; void reset(){l=IMAX,r=0,u=IMAX,d=0;} }; rectangle a[MAX]; int H,W,kind=0,indegree[MAXN]; char in[MAX][MAX]; bool visin[MAXN],map1[MAX][MAX],vis[MAXN]; map<char,int> number; map<int,char> word; map<string,bool> hash; string empty; vector<string> ans; void pre_group() { for(int i=1;i<=kind;i++) { for(int j=a[i].l;j<=a[i].r;j++) { if(in[a[i].u][j]!=word[i] && in[a[i].u][j]!='.') map1[i][number[in[a[i].u][j]]]=true; if(in[a[i].d][j]!=word[i] && in[a[i].d][j]!='.') map1[i][number[in[a[i].d][j]]]=true; } for(int j=a[i].u;j<=a[i].d;j++) { if(in[j][a[i].l]!=word[i] && in[j][a[i].l]!='.') map1[i][number[in[j][a[i].l]]]=true; if(in[j][a[i].r]!=word[i] && in[j][a[i].r]!='.') map1[i][number[in[j][a[i].r]]]=true; } } for(int i=1;i<=kind;i++) for(int j=1;j<=kind;j++) if(map1[i][j]) indegree[j]++; } void topsort(int floor,string now) { if(floor==kind+1 && !hash[now]) { hash[now]=true; ans.push_back(now); return; } for(int i=1;i<=kind;i++) { if(indegree[i]==0 && !vis[i]) { vis[i]=true; indegree[i]=-1; for(int j=1;j<=kind;j++) if(map1[i][j]) indegree[j]--; topsort(floor+1,now+(char)word[i]); for(int j=1;j<=kind;j++) if(map1[i][j]) indegree[j]++; indegree[i]=0; vis[i]=false; } } } int main() { freopen("frameup.in","r",stdin); freopen("frameup.out","w",stdout); scanf("%d%d",&H,&W); for(int i=1;i<=H;i++) { scanf("\n"); for(int j=1;j<=W;j++) { scanf("%c",&in[i][j]); if(!visin[in[i][j]] && in[i][j]!='.') { kind++; visin[in[i][j]]=true; number[in[i][j]]=kind; word[kind]=in[i][j]; a[number[in[i][j]]].reset(); } a[number[in[i][j]]].l=min(j,a[number[in[i][j]]].l); a[number[in[i][j]]].r=max(j,a[number[in[i][j]]].r); a[number[in[i][j]]].u=min(i,a[number[in[i][j]]].u); a[number[in[i][j]]].d=max(i,a[number[in[i][j]]].d); } } pre_group(); topsort(1,empty); sort(ans.begin(),ans.end()); for(int i=0;i<(int)ans.size();i++) cout<<ans[i]<<endl; //system("pause"); return 0; }
【评测信息】:
TASK: frameup
LANG: C++
Compiling...
Compile: OK
Executing...
Test 1: TEST OK [0.011 secs, 3524 KB]
Test 2: TEST OK [0.011 secs, 3524 KB]
Test 3: TEST OK [0.011 secs, 3524 KB]
Test 4: TEST OK [0.011 secs, 3524 KB]
Test 5: TEST OK [0.011 secs, 3524 KB]
Test 6: TEST OK [0.011 secs, 3524 KB]
Test 7: TEST OK [0.011 secs, 3524 KB]
Test 8: TEST OK [0.205 secs, 3656 KB]
Test 9: TEST OK [0.454 secs, 3920 KB]
All tests OK.
YOUR PROGRAM ('frameup') WORKED FIRST TIME!
That's fantastic-- and a rare thing. Please accept these special automatedcongratulations.
转载注明出处:http://blog.csdn.net/u011400953
相关文章推荐
- 【USACO题库】4.4.3 Frame Up重叠的图像
- 【USACO4.4.3】重叠的图像(DAG图的拓扑排序)
- usaco 4.4.3 Frame Up
- USACO Training 3.4.2 American Heritage 题解与分析
- USACO 4.3.4 Letter Game 字母游戏 题解与分析
- usaco 4.4.3 Frame Up
- USACO Training 4.2.3 Job Processing 工序安排 题解与分析
- C++11——【USACO 4.4.3】——Frame Up
- BZOJ 1601 [Usaco2008 Oct]灌水 题解与分析
- USACO 4.4.2 Pollutant Control追查坏牛奶 题解与分析
- USACO4.4.3 Frame Up (frameup)
- USACO 5.1.1 Fencing the Cows 圈奶牛 题解与分析
- USACO 4.4.1 Shuttle Puzzle 棋盘游戏 题解与分析
- USACO Training 4.2.1 Drainage Ditches 草地排水 题解与分析<网络流DINIC算法>
- usaco training 4.4.3 Frame Up 题解
- USACO Training 3.3.3 Camelot 亚瑟王的宫殿 题解与分析
- 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码
- USACO4.4.3 Frame Up (frameup)
- USACO Training 5.3.3 Network of Schools 校园网 题解与分析
- Camera 图像处理原理分析