pku1376 Robot
第一道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;
}
#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;
}