题意:给一幅图是几张图叠起来以后的效果,问这几张图是按照什么顺序叠起来的。
思路:由于每张图四条边都至少能看见一个字符,由此可以推出该图片的大小,在该图片边界上出现的图片就是覆盖它的图片,由此建图,输出全拓扑序列。
1Y。可能细节比较多一点。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
#include <stack>
#define MAXN 1000
using namespace std;
typedef struct CsNode
{
int data;
bool vis;
CsNode *parent,*firstchild,*nextsibling;
} CsNode,*toptree;
int n;
int in[MAXN];
char val[MAXN];
void process(vector<int> gl[],stack<int> &sk,int p)
{
in[p]--;
for(int i=0; i<gl[p].size(); ++i)
in[gl[p][i]]--;
for(int i=0; i<n; ++i)
if(!in[i]) sk.push(i);
}
void addinagree(vector<int> gl[],int p)
{
in[p]++;
for(int i=0; i<gl[p].size(); ++i)
in[gl[p][i]]++;
}
void createtoptree(vector<int> gl[])
{
CsNode *head;
head=new CsNode;
head->data=head->vis=head->vis=head->parent=head->firstchild=head->nextsibling=NULL;
CsNode *T;
T=head;
stack<int> sk;
int cd[MAXN]= {0},cdlen=0;
for(int i=0; i<n; ++i)
if(!in[i]) sk.push(i);
CsNode *p;
while(!sk.empty())
{
while(!sk.empty())
{
while(!sk.empty())
{
int gettop=sk.top();
sk.pop();
p=new CsNode;
p->parent=T;
p->firstchild=NULL;
p->data=gettop;
p->vis=false;
p->nextsibling=T->firstchild;
if(p->nextsibling) p->nextsibling->parent=p;
T->firstchild=p;
}
T=T->firstchild;
int pos=T->data;
cd[cdlen++]=pos;
process(gl,sk,pos);
}
cd[cdlen]=-1;
int k=0;
while(cd[k]!=-1)
{
char c=val[cd[k]];
printf("%c",c);
k++;
}
printf("\n");
while((p->nextsibling==0||p->vis==true)&&p->parent!=0)
{
if(p->vis==false)
{
int pos=p->data;
addinagree(gl,pos);
cdlen--;
}
p->vis=false;
CsNode *q=p;
p=p->parent;
delete q;
}
if(p->nextsibling&&!p->vis)
{
p->vis=true;
int pos=p->data;
addinagree(gl,pos);
cdlen--;
T=p->nextsibling;
pos=T->data;
cd[cdlen++]=pos;
process(gl,sk,pos);
}
}
}
struct Rectangle
{
char name;
int u,d,l,r;
Rectangle()
{
u=50;
l=50;
d=-50;
r=-50;
}
void cmp(int i,int j)
{
u=min(u,i);
d=max(d,i);
l=min(l,j);
r=max(r,j);
}
bool operator < (Rectangle r) const
{
return name<r.name;
}
};
void addedge(int v,int u,vector<int> gl[])
{
if(gl[u].end()==find(gl[u].begin(),gl[u].end(),v))
{
in[v]++;
gl[u].push_back(v);
}
}
int main()
{
int h,w;
while(scanf("%d%d",&h,&w)!=EOF)
{
char grid[35][35]= {0};
for(int i=0; i<h; ++i)
scanf("%s",grid[i]);
n=0;
map<char ,int > cur;
map<char ,bool > appear;
Rectangle rec[MAXN];
for(int i=0; i<h; ++i)
for(int j=0; j<w; ++j)
{
char c=grid[i][j];
if(c!='.')
{
if(!appear[c])
{
appear[c]=true;
rec[n].name=c;
cur[c]=n++;
}
int pos=cur[c];
rec[pos].cmp(i,j);
}
}
memset(val,0,sizeof(val));
memset(in,0,sizeof(in));
sort(rec,rec+n);
map<char,int> mp;
for(int i=0; i<n; ++i)
{
val[i]=rec[i].name;
mp[rec[i].name]=i;
}
vector<int> g[MAXN];
for(int i=0; i<n; ++i)
{
char c=rec[i].name;
int u=rec[i].u,l=rec[i].l,r=rec[i].r,d=rec[i].d;
for(int j=l; j<=r; ++j)
{
char uu=grid[u][j],dd=grid[d][j];
if(uu!=c&&uu!='.') addedge(mp[uu],mp[c],g);
if(dd!=c&&dd!='.') addedge(mp[dd],mp[c],g);
}
for(int j=u; j<=d; ++j)
{
char ll=grid[j][l],rr=grid[j][r];
if(ll!=c&&ll!='.') addedge(mp[ll],mp[c],g);
if(rr!=c&&rr!='.') addedge(mp[rr],mp[c],g);
}
}
createtoptree(g);
}
return 0;
}