链接:https://vjudge.net/problem/POJ-1128
题意:
每张图片上面画了一些边框,给出这些边框叠在一起后的图片,图片边框一定是由一个字母表示并且每条边至少三个字符,输入保证至少会给出边框每条边的一个字母,一个角的一个字符表示两条边,图片边框用大写字母表示,并且不会有两张图片的边框使用同一个大写字母,求从下往上的重叠顺序,如果有多种结果的话就按照字典序输出所有结果
思路:
先建图,找每个图内部的图片个数,同时记录。
因为不用种类的都要输出,按照从小到大的字典序去DFS。
代码:
#include <iostream> #include <memory.h> #include <vector> #include <map> #include <algorithm> #include <cstdio> #include <math.h> #include <queue> #include <string> #include <stack> #include <iterator> #include <stdlib.h> #include <time.h> #include <assert.h> using namespace std; typedef long long LL; const int MAXN = 30 + 10; char G[MAXN][MAXN]; char res[MAXN]; int M[MAXN][MAXN]; int Vis[MAXN]; int in[MAXN]; int n, m, cnt; void Init() { cnt = 0; memset(Vis, 0, sizeof(Vis)); memset(in, 0, sizeof(in)); memset(M, 0, sizeof(M)); } void DFS(int num) { if (num == cnt) { res[num] = ' '; cout << res << endl; return; } for (int i = 0;i < 26;i++) { if (in[i] == 0 && Vis[i]) { res[num] = 'A'+i; in[i] = -1; for (int j = 0;j < 26;j++) if (M[i][j]) --in[j]; DFS(num+1); in[i] = 0; for (int j = 0;j < 26;j++) if (M[i][j]) ++in[j]; } } return; } int main() { while (cin >> n >> m) { Init(); for (int i = 1;i <= n;i++) for (int j = 1;j <= m;j++) cin >> G[i][j]; for (int k = 0;k < 26;k++) { int x1 = MAXN, y1 = MAXN, x2 = -1, y2 = -1; for (int i = 1;i <= n;i++) for (int j = 1;j <= m;j++) { if (G[i][j] == 'A'+k) { x1 = min(x1, i); y1 = min(y1, j); x2 = max(x2, i); y2 = max(y2, j); } } if (x1 == MAXN || y1 == MAXN || x2 == -1 || y2 == -1) continue; Vis[k] = 1; cnt++; for (int i = x1;i <= x2;i++) { for (int j = y1;j <= y2;j++) { if (i == x1 || i == x2 || j == y1 || j == y2) { if (G[i][j] != 'A'+k && G[i][j] != '.') { int t = G[i][j]-'A'; if (!M[k][t]) ++in[t], M[k][t] = 1; } } } } } DFS(0); } return 0; }