/*------------------------------------------------------------------------------ * problem021.cc: Edit Step Ladders (9.6.5) **----------------------------------------------------------------------------*/ /* Copyright (c) 2009 Peter Bui. All Rights Reserved. * * Peter Bui * **------------------------------------------------------------------------------ * Includes **----------------------------------------------------------------------------*/ #include #include #include #include #include #include using namespace std; /*------------------------------------------------------------------------------ * Constants **----------------------------------------------------------------------------*/ #define MAX_STRLEN 17 /*------------------------------------------------------------------------------ * Data Structures **----------------------------------------------------------------------------*/ typedef set Edges; typedef map Graph; typedef map Mark; /*------------------------------------------------------------------------------ * Functions **----------------------------------------------------------------------------*/ static void read_nodes(Graph &g) { string s; while (cin >> s) g[s] = set(); } static int min(int a, int b, int c) { int m; m = (a < b ? a : b); m = (m < c ? m : c); return (m); } /* LevenshteinDistance Algorithm * http://en.wikipedia.org/wiki/Levenshtein_distance */ static int edit_distance(const string &s1, const string &s2) { int d[MAX_STRLEN][MAX_STRLEN]; int i, j; for (i = 0; i <= s1.size(); i++) d[i][0] = i; for (j = 0; j <= s2.size(); j++) d[0][j] = j; for (j = 1; j <= s2.size(); j++) for (i = 1; i <= s1.size(); i++) if (s1[i - 1] == s2[j - 1]) d[i][j] = d[i - 1][j - 1]; else d[i][j] = min(d[i - 1][j], d[i][j - 1], d[i - 1][j - 1]) + 1; return (d[s1.size()][s2.size()]); } static bool is_edit_step(const string &s1, const string &s2) { size_t i, c; if (abs((long int)(s1.size() - s2.size())) > 1) return (false); if (s1 >= s2) return (false); return (edit_distance(s1, s2) == 1); } static void form_edges(Graph &g) { Graph::iterator it, jt; for (it = g.begin(); it != g.end(); it++) for (jt = g.begin(); jt != g.end(); jt++) if (is_edit_step(it->first, jt->first)) it->second.insert(jt->first); } static int dfs(Graph &g, Mark &m, const string &s, int d) { Edges::iterator et; int dtmp, dmax; dmax = d; m[s] = true; for (et = g[s].begin(); et != g[s].end(); et++) { if (!m[*et]) { dtmp = dfs(g, m, *et, d + 1); if (dtmp > dmax) dmax = dtmp; } } return (dmax); } static int dfs_all(Graph &g) { Graph::iterator gt; Mark m; int dtmp, dmax; dmax = 0; for (gt = g.begin(); gt != g.end(); gt++) { dtmp = dfs(g, m, gt->first, 1); if (dtmp > dmax) dmax = dtmp; m.clear(); } return (dmax); } static void print_graph(Graph &g) { Graph::iterator gt; Edges::iterator et; for (gt = g.begin(); gt != g.end(); gt++) { cout << gt->first << ":"; for (et = gt->second.begin(); et != gt->second.end(); et++) cout << ' ' << *et; cout << endl; } } /*------------------------------------------------------------------------------ * Main Execution **----------------------------------------------------------------------------*/ int main(int argc, char* argv[]) { Graph g; read_nodes(g); form_edges(g); //print_graph(g); cout << dfs_all(g) << endl; return (EXIT_SUCCESS); } /*------------------------------------------------------------------------------ * vim: sts=4 sw=4 ts=8 ft=cpp **----------------------------------------------------------------------------*/