/* 问题描述: 目标状态为: 1 2 3 4 5 6 7 8 0 输入初始状态,求初始状态到最终状态的路径分别 用u(向上),d(向下),l(向左),r(向右)来表示四个方向的移动; 如果有解,则输出路径,否则输出"unsolvable" 有多个输入 */ #include<iostream> #include<queue> #include<string> #include<cstring> using namespace std; long long fac[10] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 }; const int direction[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; //0移动的方向 bool closeList[362880 + 10]; //记录一个节点是否被访问过 // l , r, u, d char action[5] = "udlr"; //移动的步骤,对应上面的direction int target = 0; //保存目标状态的康托展开值 int tmptarget[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 0 }; //目标状态 const int num = 3; struct Node{ int state[num * num]; int zero; //0的位置 string steps; //从初始节点到当前节点的路径 int cnt; //当前状态的康托展开值 }; //康托展开 int Cantor(int state[9]){ int id = 0; for (size_t i = 0; i < num * num; i++){ int count = 0; for (size_t j = i + 1; j < num * num; j++){ if (state[i] > state[j]) count++; } id += (count * fac[num * num - i - 1]); } return id + 1; } int main(int argc, char *argv[]){ target = Cantor(tmptarget); char ch; //1 2 3 4 5 x 7 8 6 //2 3 4 1 5 x 7 6 8 while (cin >> ch){ //记得把cin >> ch放在这里,否则会time limit Node head; Node next; if (ch == 'x'){ head.zero = 0; head.state[0] = 0; } else head.state[0] = ch - '0'; for (int i = 1; i < num * num; i++){ cin >> ch; //输入起始状态 if (ch == 'x'){ //把x换成0 head.zero = i; head.state[i] = 0; } else head.state[i] = ch - '0'; } head.cnt = Cantor(head.state); head.steps = ""; queue<Node> openList; bool flag = false; //记录是否达到目标状态 string path = ""; //记录从起始节点到目标节点的路径 memset(closeList, false, sizeof(closeList)); openList.push(head); while (!openList.empty() && !flag){ head = openList.front(); if (head.cnt == target){ //判断是否达到目标状态 flag = true; path = head.steps; break; } int oldr = head.zero / num; //0所在的行 int oldc = head.zero % num; //0所在的列 for (int i = 0; i < 4; i++){ int newr = oldr + direction[i][0]; int newc = oldc + direction[i][1]; if (newr >= 0 && newr < num && newc >= 0 && newc < num){ next = head; next.zero = newr * 3 + newc; //0的新位置 next.state[head.zero] = head.state[next.zero]; next.state[next.zero] = 0; next.cnt = Cantor(next.state); if (!closeList[next.cnt]){ next.steps = head.steps + action[i]; if (next.cnt == target){ flag = true; path = next.steps; break; } closeList[next.cnt] = true; openList.push(next); } } } openList.pop(); } if (flag){ //找到解,输出路径 cout << path << "\n"; } else{ cout << "unsolvable" << "\n"; } } return 0; }
原文地址:http://blog.csdn.net/liujan511536/article/details/42556883