DivI lev2 #include <iostream> #include <list> #include <vector> #include <cstring> #include <queue> #include <iterator> #include <algorithm> #include <sstream> using namespace std; #define NODE_NUM (26 * 26 * 26 * 26) typedef struct node { long distance; } node; class SmartWordToy { private: node * vertex; short * visited; vector<string> pattern; public: long str2id(string str) { long sum = 0; for (int i= 0; i < 4; i++) { sum = sum * 26 + str[i] - 'a'; } return sum; } string id2str(long id) { string str(4, 'a'); for (int i = 3; i >= 0; i--) { str[i] = ('a' + id % 26); id /= 26; } return str; } public: SmartWordToy() { vertex = new node[NODE_NUM]; memset(vertex, -1, sizeof(node) * NODE_NUM); visited = new short[NODE_NUM]; memset(visited, 0, sizeof(short) * NODE_NUM); } ~SmartWordToy() { delete [] vertex; } int minPresses(string start, string finish, vector<string> forbid) { // construct pattern for (int i = 0; i < forbid.size(); i++) { istringstream iss(forbid[i]); string sub; while (iss >> sub) { pattern.push_back(sub); } } // find the shortest path queue<long> q; long start_id = str2id(start); vertex[start_id].distance = 0; visited[start_id] = 1; q.push(start_id); while (!q.empty()) { long cur_id = q.front(); q.pop(); string cur_str= id2str(cur_id); if (cur_str == finish) return vertex[cur_id].distance; for (int i = 0; i < 4; i++) for (int j = -1; j <= 1; j += 2) { string tmp_str = cur_str; tmp_str[i] += j; tmp_str[i] = (tmp_str[i] - 'a' + 26) % 26 + 'a'; long next_id = str2id(tmp_str); if (visited[next_id] == 1) continue; short forbid_flg = 0; for (int k = 0; k < forbid.size(); k++) { int match = 0; for (int l = 0; l < 4; l++) { size_t found = pattern[k * 4 + l].find(tmp_str[l]); if (found != string::npos) match++; else break; } if (match == 4) { forbid_flg = 1; break; } } if (forbid_flg == 0) { vertex[next_id].distance = vertex[cur_id].distance + 1; visited[next_id] = 1; q.push(next_id); } } } return -1; } }; int main() { SmartWordToy swt; // cout << swt.str2id("abcd") << endl; // cout << swt.id2str(731) << endl; string start("aaaa"); string finish("zzzz"); vector<string> forbid; forbid.push_back("bz a a a"); forbid.push_back("a bz a a"); forbid.push_back("a a bz a"); forbid.push_back("a a a bz"); cout << swt.minPresses(start, finish, forbid) << endl; return 0; }