百度之星初赛一--Mindis--思维建图

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);
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值