平面上有 n 个矩形,矩形的边平行于坐标轴,现在度度熊需要操控一名角色从 A 点走到 B 点。
该角色可以上下左右移动,在恰被 k 个矩形覆盖的区域,该角色的速率为 k+1 个距离/秒(矩形覆盖区域包括边界)。
请求出 A 移动到 B 最快需要多少秒。
input
第一行一个整数 T (1≤T≤5) 表示数据组数。
对于每组数据,第一行输入一个整数 n (1≤n≤200)。
接下来 n 行每行 4 个整数 x1,y1,x2,y2 (0≤x1<x2≤1000000000,0≤y1<y2≤1000000000),分别表示矩形的左下角和右上角的坐标。
最后一行四个整数 xa,ya,xb,yb ((0≤xa,xb,ya,yb≤1000000000) 代表 A 和 B 的坐标。
Output
对于每组数据,输出一个小数表示答案。答案保留 5 位小数。
Sample Input
1 1 5 5 6 6 7 7 8 8
Sample Output
2.00000
思路:第一步肯定是将有用的坐标离散化, x1,y1,x2,y2 sx,sy,ex,ey这些有用的坐标肯定都要离散化(有些题目可能有些有用的坐标忘记离散化了,离散化的时候要想一下哪些坐标有用) 离散化后然后就讨论怎么加矩形覆盖,这样加更方便既:在加一个x1,x2,y1,y2的矩形的时候用一个sumx[x][y]记录 x1 y1 ,x2-1 y2 的矩形,既最右边那一行没有加;同理sumy记录的一个矩形最上面那一行没有加,这样在处理速度的时候特别方便(具体看代码);然后相邻的点建边跑最短路即可,但是要注意一点 不能用vis标记已经访问过的点 以前跑最短路的时候第一次出来的权值一定是最小的,后面出来肯定最大,但是这个题目不一样;
#include<bits/stdc++.h>
using namespace std;
#define LL long long
typedef pair<LL,LL>P;
const int len=5e2+9;
const LL mod=998244353;
int a[len],b[len],x1[len],x2[len],y11[len],y2[len];
int tota,totb,sx,sy,ex,ey;
int getx(int x){return lower_bound(a+1,a+1+tota,x)-a;}
int gety(int x){return lower_bound(b+1,b+1+totb,x)-b;}
double numx[len][len],numy[len][len],dis[len][len];
struct Node{
int x,y;
bool operator<(const Node a)const
{return dis[x][y]>=dis[a.x][a.y];}
};
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
void bfs()
{
for(int i=1;i<=tota;++i)
for(int j=1;j<=totb;++j)
dis[i][j]=1e18;
priority_queue<Node,vector<Node>,less<Node> >qu;
qu.push({sx,sy});
dis[sx][sy]=0;
while(qu.size())
{
Node p=qu.top();qu.pop();
for(int i=0;i<4;++i)
{
int xx=p.x+dx[i];
int yy=p.y+dy[i];
if(xx<=0||xx>tota||yy<=0||yy>totb)continue;
double w;
if(xx==p.x)w=fabs(b[p.y]-b[yy])/numy[xx][min(p.y,yy)];
else w=fabs(a[p.x]-a[xx])/numx[min(xx,p.x)][p.y];
if(dis[p.x][p.y]+w<dis[xx][yy])
{
dis[xx][yy]=w+dis[p.x][p.y];
qu.push({xx,yy});
}
}
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
tota=totb=0;
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d%d%d%d",&x1[i],&y11[i],&x2[i],&y2[i]);
a[++tota]=x1[i];
a[++tota]=x2[i];
b[++totb]=y11[i];
b[++totb]=y2[i];
}
scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
a[++tota]=sx;b[++totb]=sy;
a[++tota]=ex;b[++totb]=ey;
sort(a+1,a+1+tota);
sort(b+1,b+1+totb);
tota=unique(a+1,a+1+tota)-a-1;
totb=unique(b+1,b+1+totb)-b-1;
sx=getx(sx);sy=gety(sy);
ex=getx(ex);ey=gety(ey);
for(int i=1;i<=tota;++i)
for(int j=1;j<=totb;++j)
numx[i][j]=numy[i][j]=1;
for(int i=1;i<=n;++i)
{
x1[i]=getx(x1[i]);
x2[i]=getx(x2[i]);
y11[i]=gety(y11[i]);
y2[i]=gety(y2[i]);
for(int j=x1[i];j<x2[i];++j)
for(int k=y11[i];k<=y2[i];++k)
numx[j][k]++;
for(int j=x1[i];j<=x2[i];++j)
for(int k=y11[i];k<y2[i];++k)
numy[j][k]++;
}
bfs();
printf("%.5lf\n",dis[ex][ey]);
}
}