POJ 1077 Eight bfs
这题一开始做,什么优化都没做, 直接MLM+TLM, 后来用了康托展开+双向bfs过了,注意这题答案不唯一,开始与sample给的例子不同,以为自己错了,后来发现两个都对,果断交上去,结果AC掉了~
#include <iostream> #include <string> #include <queue> #include <memory.h> using namespace std; struct status { int x_x, x_y; int a; string path; }; int fact[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; int isvisit[362880]; string path[362880]; char oper_name[] = {'u','d','l','r'}; char opposite_oper[] = {'d', 'u', 'r', 'l'}; bool do_operate(int, const status&, status&); void bfs(); bool is_goal(const status&); int encode(int); int start; int goal = 123456789; int x_x, x_y; int main() { char c; int tmp[9]; memset(isvisit, false, sizeof(isvisit)); while (cin >> c) { for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { if (c == 'x') { tmp[3*i+j] = 9; x_x = i; x_y = j; } else tmp[3*i+j] = c - '0'; if (!(i == 2 && j == 2)) cin >> c; } start = tmp[0]*1e8 + tmp[1]*1e7 + tmp[2]*1e6 + tmp[3]*1e5 + tmp[4]*1e4 + tmp[5]*1e3 + tmp[6]*1e2 + tmp[7]*10 + tmp[8]; bfs(); memset(isvisit, false, sizeof(isvisit)); } return 0; } void bfs() { queue<status> Q1, Q2; bool flag; status p, next; p.a = start; p.path = ""; p.x_x = x_x; p.x_y = x_y; int code; isvisit[encode(p.a)] = 1; Q1.push(p); p.a = goal; p.x_x = 2; p.x_y = 2; isvisit[encode(p.a)] = 2; Q2.push(p); while (!Q1.empty()) { p = Q1.front(); Q1.pop(); if (p.a == goal) { cout << p.path << endl; return ; } for (int i = 0; i < 4; i++) { flag = do_operate(i, p, next); next.path = p.path + oper_name[i]; code = encode(next.a); if (flag ) { if (isvisit[code] == 0) { isvisit[code] = 1; path[code] = next.path; Q1.push(next); } else if (isvisit[code] == 2) { cout << next.path << path[code] << endl; return; } } } p = Q2.front(); Q2.pop(); for (int i = 0; i < 4; i++) { flag = do_operate(i, p, next); next.path = opposite_oper[i]+p.path; code = encode(next.a); if (flag) { if (isvisit[code] == 0) { isvisit[code] = 2; path[code] = next.path; Q2.push(next); } else if (isvisit[code] == 1) { cout << path[code] << next.path << endl; return; } } } } cout << "unsolvable" << endl; } bool do_operate(int mode, const status& p, status & s) { s = p; int num = p.a; int tmp[9]; for (int i = 8; i >= 0; i--) { tmp[i] = num%10; num /= 10; } switch (mode) { case 0: if (p.x_x > 0) { swap(tmp[3*s.x_x + s.x_y],tmp[3*(s.x_x-1) + s.x_y]); s.x_x = s.x_x-1; s.x_y = s.x_y; s.a = tmp[0]*1e8 + tmp[1]*1e7 + tmp[2]*1e6 + tmp[3]*1e5 + tmp[4]*1e4 + tmp[5]*1e3 + tmp[6]*1e2 + tmp[7]*10 + tmp[8]; } else return false; break; case 1: if (p.x_x < 2) { swap(tmp[3*s.x_x + s.x_y],tmp[3*(s.x_x+1) + s.x_y]); s.x_x = p.x_x+1; s.x_y = p.x_y; s.a = tmp[0]*1e8 + tmp[1]*1e7 + tmp[2]*1e6 + tmp[3]*1e5 + tmp[4]*1e4 + tmp[5]*1e3 + tmp[6]*1e2 + tmp[7]*10 + tmp[8]; } else return false; break; case 2: if (p.x_y > 0) { swap(tmp[3*s.x_x + s.x_y],tmp[3*(s.x_x) + s.x_y-1]); s.x_x = p.x_x; s.x_y = p.x_y-1; s.a = tmp[0]*1e8 + tmp[1]*1e7 + tmp[2]*1e6 + tmp[3]*1e5 + tmp[4]*1e4 + tmp[5]*1e3 + tmp[6]*1e2 + tmp[7]*10 + tmp[8]; } else return false; break; case 3: if (p.x_y < 2) { swap(tmp[3*s.x_x + s.x_y],tmp[3*(s.x_x) + s.x_y+1]); s.x_x = p.x_x; s.x_y = p.x_y+1; s.a = tmp[0]*1e8 + tmp[1]*1e7 + tmp[2]*1e6 + tmp[3]*1e5 + tmp[4]*1e4 + tmp[5]*1e3 + tmp[6]*1e2 + tmp[7]*10 + tmp[8]; } else return false; break; } return true; } int encode(int num) { int tmp[9]; int cnt; for (int i = 8; i >= 0; i--) { tmp[i] = num%10; num /= 10; } for (int i = 0; i < 9; i++) { cnt = 0; for (int j = i+1; j < 9; j++) if (tmp[i] > tmp[j]) cnt++; num += cnt*fact[8-i]; } return num; }