トポロジカルソートする。
const int N = CHAR_MAX + 1; bool g[N][N]; const string error = "ERROR!"; string tsort(const vector<char> &C) { string ord; priority_queue< char, vector<char>, greater<char> > u; int deg[N]; fill(deg, deg + N, 0); for (int i = 0; i < C.size(); ++i) { for (int j = 0; j < C.size(); ++j) { int src = C[i]; int dst = C[j]; if (g[src][dst]) ++deg[dst]; } } for (int i = 0; i < C.size(); ++i) { if (deg[(int)C[i]] == 0) u.push(C[i]); } while (u.size()) { int n = u.top(); u.pop(); ord.push_back(n); for (int m = 0; m < N; ++m) { if (g[n][m]) { g[n][m] = false; if (--deg[m] == 0) u.push(m); } } } if (ord.size() != C.size()) ord = error; return ord; } class TopView { public: string findOrder(vector <string> G) { map<char, int> mnH, mnW; map<char, int> mxH, mxW; vector<char> v; const int H = G.size(); const int W = G[0].size(); const int inf = 1 << 29; for (int i = 0; i < H; ++i) { for (int j = 0; j < W; ++j) { char c = G[i][j]; if (c == '.') continue; v.push_back(c); if (mnH.count(c) == 0) mnH[c] = +inf; if (mnW.count(c) == 0) mnW[c] = +inf; if (mxH.count(c) == 0) mxH[c] = -inf; if (mxW.count(c) == 0) mxW[c] = -inf; mnH[c] = min(mnH[c], i); mnW[c] = min(mnW[c], j); mxH[c] = max(mxH[c], i); mxW[c] = max(mxW[c], j); } } sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); fill(&g[0][0], &g[N - 1][N], false); for (int k = 0; k < v.size(); ++k) { int c = v[k]; for (int i = mnH[c]; i <= mxH[c]; ++i) { for (int j = mnW[c]; j <= mxW[c]; ++j) { if (G[i][j] == '.') return error; int d = G[i][j]; g[c][d] = true; } } g[c][c] = false; } return tsort(v); } };