中级农民
- 积分
- 115
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2015-10-16
- 最后登录
- 1970-1-1
|
准备别家的时候写了个3*3的npuzzle:- auto weight = [](const string& cur) {
- int w = 0;
- for (char c = '1'; c <= '8'; ++c) {
- int id = cur.find_first_of(c);
- w += abs(id / 3 - (c - '1') / 3) + abs(id % 3 - (c - '1') % 3);
- }
- int id = cur.find_first_of(' ');
- w += abs(id / 3 - 2) + abs(id % 3 - 2);
- return w;
- };
- vector<string> NPuzzle(string input) {
- unordered_set<string> visited;
- auto comp = [](
- const pair<string, int>& a,
- const pair<string, int>& b
- ) {
- return a.second + weight(a.first) > b.second + weight(b.first);
- };
- priority_queue<pair<string, int>, vector<pair<string, int> >, decltype(comp) > pq(comp);
- pq.push({input, 0});
- unordered_map<string, string> prev;
- int di[] = {1, 0, -1, 0};
- int dj[] = {0, 1, 0, -1};
- bool found = false;
- while (not pq.empty() && !found) {
- auto p = pq.top();
- pq.pop();
- string cur = p.first;
- visited.insert(cur);
- int steps = p.second;
- int id = cur.find_first_of(' ');
- int i = id / 3;
- int j = id % 3;
- for (int k = 0; k < 4; ++k) {
- string next = cur;
- int next_i = i + di[k];
- int next_j = j + dj[k];
- if (next_i < 0 || next_i >= 3 || next_j < 0 || next_j >= 3)
- continue;
- int next_id = next_i * 3 + next_j;
- swap(next[id], next[next_id]);
- if (visited.count(next))
- continue;
- pq.push({next, steps + 1});
- prev[next] = cur;
- if (next == "12345678 ") {
- found = true;
- break;
- }
- }
- if (found)
- break;
- }
- vector<string> res;
- string tmp = "12345678 ";
- while (tmp != input) {
- res.push_back(tmp);
- tmp = prev[tmp];
- }
- reverse(res.begin(), res.end());
- return res;
- }
复制代码 不知道有没有问题。。。 |
|