by 华师小刚
这是一道较复杂的图论算法题,题目要求我们求出压入Frame的顺序,给我们已经压入所有帧的图片。我们想到,我们可以使用拓扑排序算法求出压入的顺序,前提是有一个覆盖关系的图。所以我们先利用图片,即字符数组,来建立覆盖关系图,也就是拓扑结构。该题明确指出一个帧的四边不会被完全覆盖,我们抓住一个帧的四条边处理,我们先遍历一遍字符数组,求出出现的字母,处理所有字符(除了点号)的x坐标和y坐标,放入map中。接着我们可以利用map中的坐标求出每个帧的所在的位置,然后对每个帧做这样的处理,遍历这个帧的边框,若有不属于该帧的字母,我们就建立覆盖关系。这样就有了拓扑结构,我们利用深度优先搜索(dfs)求出答案。dfs是这样实现的,我们这里采用逆拓扑排序算法,便于输出答案,每次的dfs优先选择字典序小的字母,记得回溯的时候将修改过的值恢复,当得到长度为出现字母的个数的字符串时,就输出答案然后返回。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <set>
#include <stack>
#include <vector>
using namespace std;
const int N = 50;
char g[N][N];
bool flag[N];
bool adj[N][N];
int deg[N];
int cnt;
bool vis[N] = { 0 };
char res[N];
struct Node
{
char c;
int x_min, x_max, y_min, y_max;
}st[30];
void dfs(int pos)
{
if (pos == cnt)
{
for (int i = 0; i < cnt; ++i)
{
cout << res[i];
}
cout << endl;
return;
}
for (int i = 0; i < 26; ++i)
{
if (flag[i] && deg[i] == 0 && vis[i] == false)
{
res[pos] = char(i + 'A');
vis[i] = true;
for (int j = 0; j < 26; ++j)
{
if (adj[i][j] == true)
{
deg[j] --;
}
}
dfs(pos + 1);
vis[i] = false;
for (int j = 0; j < 26; ++j)
{
if (adj[i][j] == true)
{
deg[j] ++;
}
}
}
}
return;
}
int main()
{
int row, col;
while (cin >> row >> col)
{
memset(flag, 0, sizeof(flag));
memset(adj, 0, sizeof(adj));
memset(deg, 0, sizeof(deg));
memset(vis, 0, sizeof(vis));
cnt = 0;
unordered_map<char, vector<int>> map1;
unordered_map<char, vector<int>> map2;
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < col; ++j)
{
cin >> g[i][j];
}
}
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < col; ++j)
{
if (g[i][j] != '.')
{
if (!flag[g[i][j] - 'A'])
{
flag[g[i][j] - 'A'] = true;
st[cnt].c = g[i][j];
cnt++;
}
map1[g[i][j]].push_back(i);
map2[g[i][j]].push_back(j);
}
}
}
//求出每个帧的具体位置Location
for (int i = 0; i < cnt; ++i)
{
char k = st[i].c;
sort(map1[k].begin(), map1[k].end());
st[i].y_min = map1[k][0];
st[i].y_max = map1[k][map1[k].size() - 1];
sort(map2[k].begin(), map2[k].end());
st[i].x_min = map2[k][0];
st[i].x_max = map2[k][map2[k].size() - 1];
}
//建图
for (int i = 0; i < cnt; ++i)
{
for (int x = st[i].x_min; x <= st[i].x_max; ++x)
{
if (g[st[i].y_min][x] != st[i].c)
{
if (adj[st[i].c - 'A'][g[st[i].y_min][x] - 'A'] == false)
{
adj[st[i].c - 'A'][g[st[i].y_min][x] - 'A'] = true;
deg[g[st[i].y_min][x] - 'A'] ++;
}
}
}
for (int x = st[i].x_min; x <= st[i].x_max; ++x)
{
if (g[st[i].y_max][x] != st[i].c)
{
if (adj[st[i].c - 'A'][g[st[i].y_max][x] - 'A'] == false)
{
adj[st[i].c - 'A'][g[st[i].y_max][x] - 'A'] = true;
deg[g[st[i].y_max][x] - 'A'] ++;
}
}
}
for (int y = st[i].y_min; y <= st[i].y_max; ++y)
{
if (g[y][st[i].x_min] != st[i].c)
{
if (adj[st[i].c - 'A'][g[y][st[i].x_min] - 'A'] == false)
{
adj[st[i].c - 'A'][g[y][st[i].x_min] - 'A'] = true;
deg[g[y][st[i].x_min] - 'A'] ++;
}
}
}
for (int y = st[i].y_min; y <= st[i].y_max; ++y)
{
if (g[y][st[i].x_max] != st[i].c)
{
if (adj[st[i].c - 'A'][g[y][st[i].x_max] - 'A'] == false)
{
adj[st[i].c - 'A'][g[y][st[i].x_max] - 'A'] = true;
deg[g[y][st[i].x_max] - 'A']++;
}
}
}
}
dfs(0);
}
return 0;
}