题目链接:点我啊╭(╯^╰)╮
题目大意:
中文题
解题思路:
将整个图离散化一下,注意:
由于一个矩形是一个区间,我们要考虑的是区间内的速度
所以离散化时不能左闭右开,而是计算速度的时候左闭右开
计算速度有四个方向的速度,这里只用了两个方向
BFS的过程中特判一下速度的方向即可
核心:离散区间后跑最短路
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
using pii = pair <ll,int>;
const int maxn = 2e3 + 5;
const double eps = 1e-7;
int tx[5] = {1,-1,0,0};
int ty[5] = {0,0,1,-1};
int T, n, xa, ya, xb, yb, sx, sy;
int spe1[maxn][maxn], spe2[maxn][maxn];
double ans, Time[maxn][maxn];
vector <int> lsx, lsy;
struct Node{
int x1, y1, x2, y2;
} a[maxn];
struct node{
int x, y;
double ti;
bool operator <(const node &A)const{
return ti > A.ti;
}
} ;
priority_queue <node> Q;
int getidx(int x){
return lower_bound(lsx.begin(), lsx.end(), x) - lsx.begin();
}
int getidy(int x){
return lower_bound(lsy.begin(), lsy.end(), x) - lsy.begin();
}
void bfs(int stx, int sty){
while(!Q.empty()) Q.pop();
node q, tmp;
q.x = stx, q.y = sty, q.ti = 0;
Q.push(q);
Time[q.x][q.y] = 0;
while(!Q.empty()){
q = Q.top();
Q.pop();
if(fabs(q.ti-Time[q.x][q.y]) > eps) continue;
if(q.x==xb && q.y==yb) {
ans = q.ti;
return;
}
for(int i=0; i<4; i++){
int nx = q.x + tx[i];
int ny = q.y + ty[i];
if(nx<0 || ny<0 || nx>=sx || ny>=sy) continue;
double speed1, speed2, new_ti;
int disx = abs(lsx[nx] - lsx[q.x]);
int disy = abs(lsy[ny] - lsy[q.y]);
if(tx[i] == 0) {
if(ty[i]>0) speed2 = spe2[q.x][q.y];
else speed2 = spe2[nx][ny];
new_ti = disy / speed2 + q.ti;
}
if(ty[i] == 0) {
if(tx[i]>0) speed1 = spe1[q.x][q.y];
else speed1 = spe1[nx][ny];
new_ti = disx / speed1 + q.ti;
}
if(new_ti >= Time[nx][ny]) continue;
Time[nx][ny] = new_ti;
tmp.x = nx, tmp.y = ny, tmp.ti = new_ti;
Q.push(tmp);
}
}
}
int main() {
scanf("%d", &T);
while(T--){
ans = 0;
scanf("%d", &n);
memset(spe1, 0, sizeof(spe1));
memset(spe2, 0, sizeof(spe2));
lsx.clear(), lsy.clear();
for(int i=1; i<=n; i++){
scanf("%d%d", &a[i].x1, &a[i].y1);
scanf("%d%d", &a[i].x2, &a[i].y2);
lsx.push_back(a[i].x1), lsx.push_back(a[i].x2);
lsy.push_back(a[i].y1), lsy.push_back(a[i].y2);
}
scanf("%d%d%d%d", &xa, &ya, &xb, &yb);
lsx.push_back(xa), lsx.push_back(xb);
lsy.push_back(ya), lsy.push_back(yb);
sort(lsx.begin(),lsx.end());
sort(lsy.begin(),lsy.end());
lsx.erase(unique(lsx.begin(), lsx.end()), lsx.end());
lsy.erase(unique(lsy.begin(), lsy.end()), lsy.end());
sx = lsx.size(), sy = lsy.size();
for(int i=0; i<lsx.size(); i++)
for(int j=0; j<lsy.size(); j++)
spe1[i][j]++, spe2[i][j]++, Time[i][j] = 1e15;
for(int i=1; i<=n; i++){
int x1 = getidx(a[i].x1), x2 = getidx(a[i].x2);
int y1 = getidy(a[i].y1), y2 = getidy(a[i].y2);
for(int xi=x1; xi<=x2-1; xi++)
for(int xj=y1; xj<=y2; xj++)
spe1[xi][xj]++;
for(int xi=x1; xi<=x2; xi++)
for(int xj=y1; xj<=y2-1; xj++)
spe2[xi][xj]++;
}
xa = getidx(xa), ya = getidy(ya);
xb = getidx(xb), yb = getidy(yb);
bfs(xa, ya);
printf("%.5f\n", ans);
}
}
/*
100
2
0 1 2 2
1 1 3 2
0 0 3 3
*/