您的位置:首页 > 其它

USACO 4.4.3 Frame Up 重叠的图像 题解与分析

2013-09-18 21:36 337 查看
Frame Up 重叠的图像

译 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: frameup

INPUT 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

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: