2011-04-07 13:41:12Morris
A* Algorithm (A-Star)
/**********************************************************************************/
/* Problem: d747 "迷宮路徑" from A* (A-star) */
/* Language: C */
/* Result: AC (476ms, 4837KB) on ZeroJudge */
/* Author: morris1028 at 2011-04-07 13:37:12 */
/**********************************************************************************/
#include<stdio.h>
#include<stdlib.h>
struct Heap {
short x, y;
int F;
}Heap[1000000], T;
struct Mark {
short x, y;
}Mark[1000000];
int CntStep[1000][1000]={0};
int Sx, Sy, Gx, Gy, dx1, dy1, dx2, dy2, L;
char Map[1000][1001];
/*Heap以下*/
void Swap(int P, int S) {
T=Heap[P], Heap[P]=Heap[S], Heap[S]=T;
}
void Insert () {
int S=L, P=L/2;
while(S >= 2 && Heap[P].F > Heap[S].F)
Swap(P,S), S=P, P=S/2;
}
void Delete () {
int P=1, S=2*P;
Swap(1, L), L--;
while(S <= L) {
if(S < L && Heap[S+1].F < Heap[S].F) S++;
if(Heap[P].F <= Heap[S].F) break;
Swap(P, S), P=S, S=2*P;
}
}
/*Heap以上*/
/*A-Star以下*/
int H(int Cx, int Cy) {
dx1=Cx-Gx, dy1=Cy-Gy;
return abs(dx1*dy2-dx2*dy1)+(abs(Cx-Gx)+abs(Cy-Gy))*1000000;
}
void Judge(int Nx, int Ny, int Cx, int Cy) {
if(Map[Nx][Ny]!='X' && (CntStep[Nx][Ny]>CntStep[Cx][Cy]+1 || CntStep[Nx][Ny]==0))
CntStep[Nx][Ny]=CntStep[Cx][Cy]+1,
Heap[++L].F=CntStep[Nx][Ny]*1000000+H(Nx,Ny), Heap[L].x=Nx, Heap[L].y=Ny,
Insert();
}
void A_Star (int Sx, int Sy, int Gx, int Gy) {
if(Map[Sx][Sy]=='X' || Map[Gx][Gy]=='X') {
puts("ERROR");
return;
}
int a, Cx, Cy, Mt=0;
L=1, dx2=Sx-Gx, dy2=Sy-Gy, Heap[1].x=Sx, Heap[1].y=Sy;
while(L > 0) {
Cx=Heap[1].x, Cy=Heap[1].y;
Mark[Mt].x=Cx, Mark[Mt++].y=Cy;
if(Cx == Gx && Cy == Gy) break;
Delete();
Judge (Cx+1, Cy, Cx, Cy);
Judge (Cx-1, Cy, Cx, Cy);
Judge (Cx, Cy+1, Cx, Cy);
Judge (Cx, Cy-1, Cx, Cy);
}
printf("%d\n", CntStep[Gx][Gy]-(!CntStep[Gx][Gy]));
/*clear record*/
for(a = 0; a < Mt; a++) CntStep[Mark[a].x][Mark[a].y]=0;
for(a = 1; a <= L; a++) CntStep[Heap[a].x][Heap[a].y]=0;
}
/*A-Star以上*/
main() {
int N, M, a;
scanf("%d %d",&N, &M); {
getchar();
for(a = 0; a < N; a++) gets(Map[a]);
for(a = 0; a< M; a++)
scanf("%d %d %d %d",&Sx,&Sy,&Gx,&Gy), A_Star(Sx,Sy,Gx,Gy);
}
return 0;
}
/* Problem: d747 "迷宮路徑" from A* (A-star) */
/* Language: C */
/* Result: AC (476ms, 4837KB) on ZeroJudge */
/* Author: morris1028 at 2011-04-07 13:37:12 */
/**********************************************************************************/
#include<stdio.h>
#include<stdlib.h>
struct Heap {
short x, y;
int F;
}Heap[1000000], T;
struct Mark {
short x, y;
}Mark[1000000];
int CntStep[1000][1000]={0};
int Sx, Sy, Gx, Gy, dx1, dy1, dx2, dy2, L;
char Map[1000][1001];
/*Heap以下*/
void Swap(int P, int S) {
T=Heap[P], Heap[P]=Heap[S], Heap[S]=T;
}
void Insert () {
int S=L, P=L/2;
while(S >= 2 && Heap[P].F > Heap[S].F)
Swap(P,S), S=P, P=S/2;
}
void Delete () {
int P=1, S=2*P;
Swap(1, L), L--;
while(S <= L) {
if(S < L && Heap[S+1].F < Heap[S].F) S++;
if(Heap[P].F <= Heap[S].F) break;
Swap(P, S), P=S, S=2*P;
}
}
/*Heap以上*/
/*A-Star以下*/
int H(int Cx, int Cy) {
dx1=Cx-Gx, dy1=Cy-Gy;
return abs(dx1*dy2-dx2*dy1)+(abs(Cx-Gx)+abs(Cy-Gy))*1000000;
}
void Judge(int Nx, int Ny, int Cx, int Cy) {
if(Map[Nx][Ny]!='X' && (CntStep[Nx][Ny]>CntStep[Cx][Cy]+1 || CntStep[Nx][Ny]==0))
CntStep[Nx][Ny]=CntStep[Cx][Cy]+1,
Heap[++L].F=CntStep[Nx][Ny]*1000000+H(Nx,Ny), Heap[L].x=Nx, Heap[L].y=Ny,
Insert();
}
void A_Star (int Sx, int Sy, int Gx, int Gy) {
if(Map[Sx][Sy]=='X' || Map[Gx][Gy]=='X') {
puts("ERROR");
return;
}
int a, Cx, Cy, Mt=0;
L=1, dx2=Sx-Gx, dy2=Sy-Gy, Heap[1].x=Sx, Heap[1].y=Sy;
while(L > 0) {
Cx=Heap[1].x, Cy=Heap[1].y;
Mark[Mt].x=Cx, Mark[Mt++].y=Cy;
if(Cx == Gx && Cy == Gy) break;
Delete();
Judge (Cx+1, Cy, Cx, Cy);
Judge (Cx-1, Cy, Cx, Cy);
Judge (Cx, Cy+1, Cx, Cy);
Judge (Cx, Cy-1, Cx, Cy);
}
printf("%d\n", CntStep[Gx][Gy]-(!CntStep[Gx][Gy]));
/*clear record*/
for(a = 0; a < Mt; a++) CntStep[Mark[a].x][Mark[a].y]=0;
for(a = 1; a <= L; a++) CntStep[Heap[a].x][Heap[a].y]=0;
}
/*A-Star以上*/
main() {
int N, M, a;
scanf("%d %d",&N, &M); {
getchar();
for(a = 0; a < N; a++) gets(Map[a]);
for(a = 0; a< M; a++)
scanf("%d %d %d %d",&Sx,&Sy,&Gx,&Gy), A_Star(Sx,Sy,Gx,Gy);
}
return 0;
}