【搜索】[POJ3897]Maze Stretching
题目
分析:显然是搜索,bfs比较慢,那就用A*吧,但是并不能直接用A*求最短路,因为在你讲迷宫拉伸了之后,你一开始找的最短路并不一定最短(我是这么觉得,自己想想),所以就二分拉伸的比例,然后用A*进行Check。
代码
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<cstring>
using namespace std;
#define MAXN 100
struct node{
int x,y;
double f,d;
bool operator<(const node &x)const{
return f>x.f;
}
};
priority_queue<node>q;
double len,f[MAXN+10][MAXN+10];
int n,m,ex,ey,dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}},T,cnt;
char s[MAXN+10][MAXN+10];
double h(int x,int y,double c){
return abs(ex-x)*c+abs(ey-y);
}
bool bfs(double c){
node p,t;
while(!q.empty()){
p=q.top();
q.pop();
if(s[p.x][p.y]=='E'){
if(p.d<len)
return 1;
return 0;
}
if(p.x==ex&&p.y==ey)
continue;
int d;
for(d=0;d<4;d++){
t=p;
if(d>1)
t.d+=c;
else
t.d++;
t.x=p.x+dir[d][0],t.y=p.y+dir[d][1];
if(s[t.x][t.y]=='#'||t.x<0||t.x>=n||t.y<0||t.y>=m)
continue;
t.f=h(t.x,t.y,c)+t.d;
if(t.f<f[t.x][t.y]){
f[t.x][t.y]=t.f;
q.push(t);
}
}
}
}
int main()
{
scanf("%d",&T);
int i,j;
node t;
while(T--){
scanf("%lf%d",&len,&n);
getchar();
for(i=0;i<n;i++)
gets(s[i]);
m=strlen(s[0]);
for(i=0;i<n;i++)
for(j=0;j<m;j++){
if(s[i][j]=='S'){
t.x=i,t.y=j;
t.d=0;
}
if(s[i][j]=='E')
ex=i,ey=j;
}
double l=0,r=10,mid;
while(r-l>1e-6){
memset(f,0x7f,sizeof f);
while(!q.empty())
q.pop();
mid=(r+l)/2;
f[t.x][t.y]=t.f=h(t.x,t.y,mid);
q.push(t);
if(bfs(mid))
l=mid;
else
r=mid;
}
printf("Case #%d: %.3lf%%\n",++cnt,mid*100);
}
}