Mindis
Accepts: 127
Submissions: 791
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
Problem Description
平面上有 nnn 个矩形,矩形的边平行于坐标轴,现在度度熊需要操控一名角色从 AAA 点走到 BBB 点。 该角色可以上下左右移动,在恰被 kkk 个矩形覆盖的区域,该角色的速率为 k+1k+1k+1 个距离/秒(矩形覆盖区域包括边界)。
请求出 AAA 移动到 BBB 最快需要多少秒。
Input
第一行一个整数 T (1≤T≤5)T~(1 \leq T \leq 5)T (1≤T≤5) 表示数据组数。 对于每组数据,第一行输入一个整数 n (1≤n≤200)n~(1 \leq n \leq 200)n (1≤n≤200)。 接下来 nnn 行每行 4 个整数 x1,y1,x2,y2 (0≤x1<x2≤1000000000,0≤y1<y2≤1000000000)x1,y1,x2,y2~(0 \leq x1 < x2 \leq 1000000000, 0 \leq y1 < y2 \leq 1000000000)x1,y1,x2,y2 (0≤x1<x2≤1000000000,0≤y1<y2≤1000000000),分别表示矩形的左下角和右上角的坐标。 最后一行四个整数 xa,ya,xb,yb ((0≤xa,xb,ya,yb≤1000000000)xa,ya,xb,yb~((0\leq xa,xb,ya,yb\leq 1000000000)xa,ya,xb,yb ((0≤xa,xb,ya,yb≤1000000000) 代表 AAA 和 BBB 的坐标。
Output
对于每组数据,输出一个小数表示答案。答案保留 5 位小数。
Sample Input
Copy
1 1 5 5 6 6 7 7 8 8
Sample Output
Copy
2.00000
把给出的各个矩形的点的横纵坐标离散化,分别存入不同的数组中,a,b。然后排序。接着,形成新的点,加边的时候,对于每一个点,只加入它的上方和右方的点,判断出他们的时间。然后跑一遍最短路。
#include <algorithm> //STL通用算法
#include <bitset> //STL位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex> //复数类
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque> //STL双端队列容器
#include <exception> //异常处理类
#include <fstream>
#include <functional> //STL定义运算函数(代替运算符)
#include <limits>
#include <list> //STL线性列表容器
#include <map> //STL 映射容器
#include <iomanip>
#include <ios> //基本输入/输出支持
#include<iosfwd> //输入/输出系统使用的前置声明
#include <iostream>
#include <istream> //基本输入流
#include <ostream> //基本输出流
#include <queue> //STL队列容器
#include <set> //STL 集合容器
#include <sstream> //基于字符串的流
#include <stack> //STL堆栈容器
#include <stdexcept> //标准异常类
#include <streambuf> //底层输入/输出支持
#include <string> //字符串类
#include <utility> //STL通用模板类
#include <vector> //STL动态数组容器
#include <cwchar>
#include <cwctype>
#define ll long long
using namespace std;
//priority_queue<int,vector<int>,less<int> >q;
int dx[]= {-1,1,0,0,-1,-1,1,1};
int dy[]= {0,0,-1,1,-1,1,1,-1};
const int maxn = 2200010+66;
const ll mod=1e9+7;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int n;
struct node
{
ll x;
ll y;
ll v;
} no[maxn],B,E;
struct rect
{
ll x;
ll y;//左下角
ll xx;
ll yy;//右上角
} rect[501];
ll a[501];
ll b[501];//记录离散化后的值
int cntx=0;
int cnty=0;
int cnt=0;
int get_Index(int x,int y)
{
return x*cnty+y+1;//标号,从1开始
}
bool ok(double x1,double y1,double x2,double y2,double x,double y)
{
if(x>=x1&&x<=x2&&y>=y1&&y<=y2)
return true;
return false;
}
double get_V(double x,double y)
{
double ans=1;
for(int i=1; i<=n; i++)
{
//cout<<(double)rect[i].x<<" "<<(double)rect[i].y<<" "<<(double)rect[i].xx<<" "<<(double)rect[i].yy<<endl;
if(ok((double)rect[i].x,(double)rect[i].y,(double)rect[i].xx,(double)rect[i].yy,x,y))
{
ans+=1.0;
}
}
return ans;
}
struct edge
{
int to;
int next;
double v;
};
struct Dij
{
edge edge[maxn];
int cnt,head[maxn],n;
double dis[maxn];
void init(int nn)
{
n=nn;
cnt=0;
for(int i=0; i<=n; i++)
head[i]=0;
}
void add(int u,int v,double w)
{
cnt++;
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt;
edge[cnt].v=w;
}
void ans(int s)
{
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>> >q;
int i,now;
for (i=1; i<=n; i++)
dis[i]=inf;
dis[s]=0;
q.push(make_pair(0,s));
while (!q.empty())
{
now=q.top().second;
q.pop();
for (i=head[now]; i; i=edge[i].next)
if (dis[now]+edge[i].v<dis[edge[i].to])
{
dis[edge[i].to]=dis[now]+edge[i].v;
q.push(make_pair(dis[edge[i].to],edge[i].to));
}
}
}
} D;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
cntx=0;
cnty=0;
cnt=0;
int bid;
int eid;
for(int i=1; i<=n; i++)
{
ll x,y;
scanf("%lld %lld",&x,&y);
a[cntx++]=x;
b[cnty++]=y;
rect[i].x=x;
rect[i].y=y;
scanf("%lld %lld",&x,&y);
a[cntx++]=x;
b[cnty++]=y;
rect[i].xx=x;
rect[i].yy=y;//右下角
}
ll x1,y1,x2,y2;
scanf("%lld %lld %lld %lld",&x1,&y1,&x2,&y2);
B.x=x1;
B.y=y1;
E.x=x2;
E.y=y2;
a[cntx++]=x1;
b[cnty++]=y1;
a[cntx++]=x2;
b[cnty++]=y2;
sort(a,a+cntx);
sort(b,b+cnty);
cntx=unique(a,a+cntx)-a;
cnty=unique(b,b+cnty)-b;//去重
cnt=cntx*cnty;
for(int i=0; i<cntx; i++)
{
for(int j=0; j<cnty; j++)
{
no[get_Index(i,j)].x=a[i];
no[get_Index(i,j)].y=b[j];
}
}
for(int i=1; i<=cnt; i++)
{
if(no[i].x==B.x&&no[i].y==B.y)
{
bid=i;
}
if(no[i].x==E.x&&no[i].y==E.y)
{
eid=i;
}
}
D.init(cnt);
for(int i=0; i<cntx; i++)
{
for(int j=0; j<cnty; j++)
{
int id=get_Index(i,j);
if(j+1<cnty)//右边的点,判断一下
{
int id1=get_Index(i,j+1);
double v=get_V((double)a[i],(double)(b[j]+b[j+1])*1.0/2);
double time=(double)(b[j+1]-b[j])*1.0/(double)v;
D.add(id,id1,time);
D.add(id1,id,time);
//cout<<id<<"---"<<id1<<"--"<<time<<"---"<<v<<endl;
/*
3
3
1 1 2 2
1 1 2 2
1 1 2 2
1 1 2 2
*/
}
if(i+1<cntx)
{
int id1=get_Index(i+1,j);
double v=get_V((double)(a[i]+a[i+1])*1.0/2,(double)(b[j]));
double time=(double)(a[i+1]-a[i])*1.0/(double)v;
D.add(id,id1,time);
D.add(id1,id,time);
//cout<<id<<"---"<<id1<<"--"<<time<<"---"<<v<<endl;
}
}
}
D.ans(bid);
double ans=D.dis[eid];
printf("%.5f\n",ans);
}
}