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;
}
浙公网安备 33010602011771号