A*
Memory:6384K Time:79MS
太烂了,估计是hash太肿...有空再来优化
#include
<
iostream
>
#include
<
string
>
#include
<
vector
>
#include
<
queue
>
using
namespace
std;
#define
MAXN 362881
int
fac[
9
]
=
{
40320
,
5040
,
720
,
120
,
24
,
6
,
2
,
1
,
1
};
int
stseq[
9
],edseq[
9
]
=
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
0
},stkey,edkey;
int
g[MAXN],f[MAXN],mk[MAXN],pre[MAXN];
char
op[MAXN];
int
h(
int
seq[
9
]){
int
i,ret
=
0
;
for
(i
=
0
;i
<
9
;i
++
)
ret
+=
abs(seq[i]
-
edseq[i]);
return
ret;
//
return 0;
}
int
getkey(
int
seq[
9
]){
int
nsn,sum
=
0
;
for
(
int
i
=
0
;i
<
9
;i
++
){
nsn
=
0
;
for
(
int
j
=
i
+
1
;j
<
9
;j
++
)
if
(seq[i]
>
seq[j])
nsn
++
;
sum
+=
nsn
*
fac[i];
}
return
sum;
}
void
getseq(
int
key,
int
*
&
seq,
int
&
pos){
//
key of "876543210" = 40319 < 40320
int
i,j,k;
for
(i
=
0
;i
<
9
;i
++
){
seq[i]
=
key
/
fac[i];
key
%=
fac[i];
}
bool
used[
9
]
=
{
0
};
used[seq[
0
]]
=
true
;
if
(seq[
0
]
==
0
)
pos
=
0
;
for
(i
=
1
;i
<
9
;i
++
){
j
=
0
;
for
(k
=
0
;j
<
seq[i]
&&
k
<
9
;k
++
)
if
(
!
used[k])
j
++
;
while
(used[k])
k
++
;
seq[i]
=
k;
used[k]
=
true
;
if
(seq[i]
==
0
)
pos
=
i;
}
}
class
CP{
public
:
int
operator
()(
int
t1,
int
t2){
return
f[t1]
>
f[t2];
}
};
void
output(
int
key){
int
*
seq,i;
string
ans
=
""
;
seq
=
new
int
[
9
];
for
(i
=
g[key]
-
1
;i
>=
0
;i
--
){
ans
+=
op[key];
key
=
pre[key];
}
for
(i
=
ans.length()
-
1
;i
>=
0
;i
--
)
cout
<<
ans[i];
cout
<<
endl;
}
int
astar(){
int
curkey,
*
curseq,pos,nkey;
curseq
=
new
int
[
9
];
memset(mk,
0
,
sizeof
(mk));
priority_queue
<
int
, vector
<
int
>
,CP
>
qu;
stkey
=
getkey(stseq);
mk[stkey]
=
1
;
g[stkey]
=
0
;
f[stkey]
=
g[stkey]
+
h(stseq);
qu.push(stkey);
f[
362880
]
=-
1
;
edkey
=
getkey(edseq);
while
(
!
qu.empty()){
curkey
=
qu.top();
qu.pop();
mk[curkey]
=
2
;
if
(curkey
==
edkey){
output(curkey);
return
g[curkey];
}
getseq(curkey,curseq,pos);
if
(pos
>=
3
){
swap(curseq[pos],curseq[pos
-
3
]);
nkey
=
getkey(curseq);
if
(mk[nkey]
==
0
){
mk[nkey]
=
1
;
pre[nkey]
=
curkey;
op[nkey]
=
'
u
'
;
g[nkey]
=
g[curkey]
+
1
;
f[nkey]
=
g[nkey]
+
h(curseq);
qu.push(nkey);
}
else
if
(mk[nkey]
==
1
){
if
(g[curkey]
+
1
<
g[nkey]){
pre[nkey]
=
curkey;
op[nkey]
=
'
u
'
;
g[nkey]
=
g[curkey]
+
1
;
f[nkey]
=
g[nkey]
+
h(curseq);
qu.push(
362880
);
qu.pop();
}
}
swap(curseq[pos],curseq[pos
-
3
]);
}
if
(pos
<
6
){
swap(curseq[pos],curseq[pos
+
3
]);
nkey
=
getkey(curseq);
if
(mk[nkey]
==
0
){
mk[nkey]
=
1
;
pre[nkey]
=
curkey;
op[nkey]
=
'
d
'
;
g[nkey]
=
g[curkey]
+
1
;
f[nkey]
=
g[nkey]
+
h(curseq);
qu.push(nkey);
}
else
if
(mk[nkey]
==
1
){
if
(g[curkey]
+
1
<
g[nkey]){
pre[nkey]
=
curkey;
op[nkey]
=
'
d
'
;
g[nkey]
=
g[curkey]
+
1
;
f[nkey]
=
g[nkey]
+
h(curseq);
qu.push(
362880
);
qu.pop();
}
}
swap(curseq[pos],curseq[pos
+
3
]);
}
if
(pos
%
3
!=
2
){
swap(curseq[pos],curseq[pos
+
1
]);
nkey
=
getkey(curseq);
if
(mk[nkey]
==
0
){
mk[nkey]
=
1
;
pre[nkey]
=
curkey;
op[nkey]
=
'
r
'
;
g[nkey]
=
g[curkey]
+
1
;
f[nkey]
=
g[nkey]
+
h(curseq);
qu.push(nkey);
}
else
if
(mk[nkey]
==
1
){
if
(g[curkey]
+
1
<
g[nkey]){
pre[nkey]
=
curkey;
op[nkey]
=
'
r
'
;
g[nkey]
=
g[curkey]
+
1
;
f[nkey]
=
g[nkey]
+
h(curseq);
qu.push(
362880
);
qu.pop();
}
}
swap(curseq[pos],curseq[pos
+
1
]);
}
if
(pos
%
3
!=
0
){
swap(curseq[pos],curseq[pos
-
1
]);
nkey
=
getkey(curseq);
if
(mk[nkey]
==
0
){
mk[nkey]
=
1
;
pre[nkey]
=
curkey;
op[nkey]
=
'
l
'
;
g[nkey]
=
g[curkey]
+
1
;
f[nkey]
=
g[nkey]
+
h(curseq);
qu.push(nkey);
}
else
if
(mk[nkey]
==
1
){
if
(g[curkey]
+
1
<
g[nkey]){
pre[nkey]
=
curkey;
op[nkey]
=
'
l
'
;
g[nkey]
=
g[curkey]
+
1
;
f[nkey]
=
g[nkey]
+
h(curseq);
qu.push(
362880
);
qu.pop();
}
}
swap(curseq[pos],curseq[pos
-
1
]);
}
}
return
-
1
;
}
int
main(){
int
i;
char
ch;
for
(i
=
0
;i
<
9
;i
++
){
cin
>>
ch;
if
(ch
==
'
x
'
)
stseq[i]
=
0
;
else
stseq[i]
=
ch
-
'
0
'
;
}
if
(astar()
==-
1
)
cout
<<
"
unsolvable\n
"
;
return
0
;
}