★实验任务
众所周知,索隆是一个路痴,一天在一小岛上,他又迷路了!!好基友山治心急如焚,
决定出去找他,由于练成了月步,山治的速度竟然达到了正无穷!小岛上除了空地,还有盘
丝洞(简称 psd) , 盘丝洞里住着可爱的妹纸,山治每次经过一个盘丝洞,都要停留一个单
位时间来欣赏妹纸,给你一个 n*m 的地图以及山治和索隆当前位置,山治想请你帮他算算他
最快要多久才能见到索隆。
★数据输入
输入第一行为两个正整数 n,m (2 <=n,m <=1000), 表示有 n 行 m 列,最左上角的坐标为
( 1,1)。
接下来 n 行,每行 m 个字符, “ .” 代表盘丝洞,“ X”代表空地,只有‘ .’和’X’两种字
符,山治通过盘丝洞需 1 个单位时间,通过空地无需花费时间。
最后两行分别表示山治和索隆的当前坐标。 (你可以假设这两个坐标都在空地上,即
‘ X’)。
★数据输出
对于每个询问,输出一行一个整数,表示山治最快见到索隆的时间。
输入示例 输出示例
6 6 3
..X...
XXX.X.
....X.
X.....
X.....
众所周知,索隆是一个路痴,一天在一小岛上,他又迷路了!!好基友山治心急如焚,
决定出去找他,由于练成了月步,山治的速度竟然达到了正无穷!小岛上除了空地,还有盘
丝洞(简称 psd) , 盘丝洞里住着可爱的妹纸,山治每次经过一个盘丝洞,都要停留一个单
位时间来欣赏妹纸,给你一个 n*m 的地图以及山治和索隆当前位置,山治想请你帮他算算他
最快要多久才能见到索隆。
★数据输入
输入第一行为两个正整数 n,m (2 <=n,m <=1000), 表示有 n 行 m 列,最左上角的坐标为
( 1,1)。
接下来 n 行,每行 m 个字符, “ .” 代表盘丝洞,“ X”代表空地,只有‘ .’和’X’两种字
符,山治通过盘丝洞需 1 个单位时间,通过空地无需花费时间。
最后两行分别表示山治和索隆的当前坐标。 (你可以假设这两个坐标都在空地上,即
‘ X’)。
★数据输出
对于每个询问,输出一行一个整数,表示山治最快见到索隆的时间。
输入示例 输出示例
6 6 3
..X...
XXX.X.
....X.
X.....
X.....
X.X...
#include<iostream>
using namespace std;
struct MinTime
{
long int x,y;
long int mintime,add;
MinTime()
{
mintime=1998;
add=0;
}
};
void buildheap(MinTime**head,MinTime*p,long int son,long int father,long int sail)
{
bool ok=1;
while(ok&&son<=sail)
{
if(son<sail&&head[son]->mintime>head[son+1]->mintime)son++;
if(p->mintime>head[son]->mintime)
{
head[father]=head[son];
father=son;
son*=2;
}
else
ok=0;
}
head[father]=p;
}
long int push(MinTime**head,MinTime*p, long int min, long int sail)
{
long int father,son;
bool ok=1;
if(head[1]->add>3)
{
buildheap(head,p,2,1,sail);
}
else
{
sail++;
son=sail;
father=son/2;
while(ok&&father>0)
{
if(head[father]->mintime>p->mintime)
{
head[son]=head[father];
son=father;
father/=2;
}
else ok=0;
}
buildheap(head,p,son*2,son,sail);
}
while(head[1]->add>3)
{
buildheap(head,head[sail],2,1,sail-1);
sail--;
}
return sail;
}
long int runtime(MinTime**MT,long int n,long int m,char**c)
{
long int xx,yy,x,y,a,b,max,sail,next[4][2]={-1,0,1,0,0,-1,0,1};
bool ok;
scanf("%d%d%d%d",&x,&y,&a,&b);
max=x>a?x-a:a-x;
max+=y>b?y-b:b-y;
x--;y--;a--;b--;
MinTime**head;
head=new MinTime*[n*m];
head[1]=&MT[x][y];
MT[x][y].mintime=0;
MT[x][y].x=x;
MT[x][y].y=y;
MT[a][b].mintime=max;
ok=1;
sail=1;
while(ok)
{
xx=head[1]->x+next[head[1]->add][0];
yy=head[1]->y+next[head[1]->add][1];
head[1]->add++;
if(xx>=0&&xx<n&&yy>=0&&yy<m)
{
if(c[xx][yy]=='.')max=head[1]->mintime+1;
else max=head[1]->mintime;
if(MT[xx][yy].mintime>max)
{
MT[xx][yy].mintime=max;
if(MT[xx][yy].mintime<MT[a][b].mintime)
{
MT[xx][yy].x=xx;
MT[xx][yy].y=yy;
sail=push(head,&MT[xx][yy],MT[a][b].mintime,sail);
}
else if(MT[head[1]->x][head[1]->y].mintime>=MT[a][b].mintime)
ok=0;
}
}
if(head[1]->add>3)
{
buildheap(head,head[sail],2,1,sail-1);
sail--;
}
}
if(c[a][b]=='.')MT[a][b].mintime--;
return MT[a][b].mintime;
}
int main()
{
long int n,m,add;
char **sign;
MinTime**MT;
scanf("%d%d",&n,&m);
MT=new MinTime*[n];
for(add=0;add<n;add++)
MT[add]=new MinTime [m];
sign=new char*[n];
for(add=0;add<n;add++)
sign[add]=new char [m+1];
for(add=0;add<n;add++)
{
scanf("%s",sign[add]);
}
n=runtime(MT,n,m,sign);
printf("%d\n",n);
for(add=0;add<n;add++)
delete MT[add];
delete MT;
return 0;
}