/* Topcoder SRM 705, D2 500-Pointer. AlphabetOrderDiv2 James S. Plank Fri Feb 3 16:23:38 EST 2017 */ #include <string> #include <vector> #include <iostream> #include <cstdio> #include <cstdlib> using namespace std; class AlphabetOrderDiv2 { public: vector < vector <int> > Adj; vector <int> Visited; string isOrdered(vector <string> words); int DFS(int n); }; int AlphabetOrderDiv2::DFS(int n) { int i; if (Visited[n] == 2) return 0; /* When visited == 2, we already know there's no cycle. */ if (Visited[n] == 1) return 1; /* However, if visited == 1, we've discovered a cycle. */ Visited[n] = 1; /* Call DFS(i) on every node where there is an edge from n to i. Return instantly if you've detected a cycle. */ for (i = 0; i < Adj[n].size(); i++) { if (Adj[n][i]) { if (DFS(i)) return 1; } } /* If there's no cycle, you can set visited to 2, and return that there is no cycle. */ Visited[n] = 2; return 0; } string AlphabetOrderDiv2::isOrdered(vector <string> words) { int i, j, c1, c2; /* I'm using an adjacenty matrix. Set it so that all entries are zero. */ Adj.resize(26); for (i = 0; i < Adj.size(); i++) Adj[i].resize(26, 0); /* Now go through the words, and set edges in the adjacency matrix. You should make sure that you don't set an edge from a node to itself. */ for (i = 0; i < words.size(); i++) { for (j = 1; j < words[i].size(); j++) { c1 = words[i][j-1] - 'a'; c2 = words[i][j] - 'a'; if (c1 != c2) Adj[c1][c2] = 1; } } /* Print the adjacency matrix. */ printf(" "); for (i = 'a'; i <= 'z'; i++) printf("%c", i); printf("\n"); for (i = 0; i < Adj.size(); i++) { printf("%c ", 'a'+i); for (j = 0; j < Adj.size(); j++) printf("%d", Adj[i][j]); printf("\n"); } /* Set all Visited fields to zero, and do a DFS on every node. If you discover a cycle, return "Impossible" */ Visited.resize(Adj.size(), 0); for (i = 0; i < Adj.size(); i++) { if (DFS(i)) return "Impossible"; } /* If you haven't found any cycles, return "Possible" */ return "Possible"; } |