第一道A*
想知道自己的启发函数有没有错的话,把函数返回值设为0再交上去看能不能通过就行了
#include
<
iostream
>
#include
<
vector
>
#include
<
queue
>
using
namespace
std;
#define
MAXN 26001
#define
tile(x,y) ((x-1)*m+y)
#define
tile_x(t) (t/m+1)
#define
tile_y(t) (t%m)
#define
hamilton(s) ((abs(tile_x(s)-tile_x(ed))+abs(tile_y(s)-tile_y(ed)))/3)
int
graph[
55
][
55
],n,m,g[MAXN],mk[MAXN],st,ed,s,x,y,op,ns,nop,f[MAXN];
char
dir[
5
];
class
CP{
public
:
int
operator
()(
int
t1,
int
t2){
return
f[t1]
>
f[t2];
}
};
int
astar(){
int
i;
f[
0
]
=-
1
;
memset(mk,
0
,
sizeof
(mk));
//
0:未入队; 1:在open队中; 2:在closed队中
priority_queue
<
int
,vector
<
int
>
,CP
>
qu;
g[st]
=
0
;
f[st]
=
g[st]
+
hamilton(st
/
10
);
qu.push(st);
mk[st]
=
1
;
while
(
!
qu.empty()){
s
=
qu.top();
qu.pop();
op
=
s
%
10
;
x
=
tile_x(s
/
10
);
y
=
tile_y(s
/
10
);
if
(s
/
10
==
ed)
return
g[s];
mk[s]
=
2
;
nop
=
(op
+
1
)
%
4
;
ns
=
s
/
10
*
10
+
nop;
if
(mk[ns]
==
0
){
g[ns]
=
g[s]
+
1
;
f[ns]
=
f[s]
+
1
;
qu.push(ns);
mk[ns]
=
1
;
}
else
if
(mk[ns]
==
1
){
if
(g[s]
+
1
<
g[ns]){
g[ns]
=
g[s]
+
1
;
qu.push(
0
);
//
更新堆
qu.pop();
}
}
nop
=
(op
+
3
)
%
4
;
ns
=
s
/
10
*
10
+
nop;
if
(mk[ns]
==
0
){
g[ns]
=
g[s]
+
1
;
f[ns]
=
f[s]
+
1
;
qu.push(ns);
mk[ns]
=
1
;
}
else
if
(mk[ns]
==
1
){
if
(g[s]
+
1
<
g[ns]){
g[ns]
=
g[s]
+
1
;
qu.push(
0
);
qu.pop();
}
}
for
(i
=
1
;i
<=
3
;i
++
){
if
(op
==
0
)
x
--
;
if
(op
==
1
)
y
++
;
if
(op
==
2
)
x
++
;
if
(op
==
3
)
y
--
;
if
(x
<=
1
||
x
>=
n
||
y
<=
1
||
y
>=
m
||
graph[x][y]
==
1
)
break
;
ns
=
tile(x,y);
ns
=
ns
*
10
+
op;
if
(mk[ns]
==
0
){
g[ns]
=
g[s]
+
1
;
f[ns]
=
g[ns]
+
hamilton(ns
/
10
);
qu.push(ns);
mk[ns]
=
1
;
}
else
if
(mk[ns]
==
1
){
if
(g[s]
+
1
<
g[ns]){
g[ns]
=
g[s]
+
1
;
qu.push(
0
);
qu.pop();
}
}
}
}
return
-
1
;
}
int
main(){
int
i,j,tmp,x,y;
while
(scanf(
"
%d%d
"
,
&
n,
&
m)
&&
n
&&
m){
memset(graph,
0
,
sizeof
(graph));
n
++
;m
++
;
for
(i
=
2
;i
<=
n;i
++
){
for
(j
=
2
;j
<=
m;j
++
){
scanf(
"
%d
"
,
&
tmp);
if
(tmp)
graph[i][j]
=
graph[i
-
1
][j]
=
graph[i][j
-
1
]
=
graph[i
-
1
][j
-
1
]
=
1
;
}
}
/*
printf("\n");
for(i=1;i<=n;i++){
for(j=1;j<=m;j++)
printf("%d ",graph[i][j]);
printf("\n");
}
printf("\n");
*/
scanf(
"
%d%d
"
,
&
x,
&
y);
x
++
;y
++
;
st
=
tile(x,y);
scanf(
"
%d%d
"
,
&
x,
&
y);
x
++
;y
++
;
ed
=
tile(x,y);
scanf(
"
%s
"
,dir);
if
(st
==
ed)
printf(
"
0\n
"
);
else
{
if
(dir[
0
]
==
'
n
'
)
st
=
st
*
10
;
if
(dir[
0
]
==
'
e
'
)
st
=
st
*
10
+
1
;
if
(dir[
0
]
==
'
s
'
)
st
=
st
*
10
+
2
;
if
(dir[
0
]
==
'
w
'
)
st
=
st
*
10
+
3
;
printf(
"
%d\n
"
,astar());
}
}
return
0
;
}