您的位置:首页 > 产品设计 > UI/UE

HDU 5033 Building

2014-10-02 21:43 260 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5033

解题报告:在一条x轴上有n个建筑物,每个建筑物有一个高度h,然后现在有q次查询,查询的内容是假设有一个人站在xi这个位置,问他看天空的视角是多大,用角度表示。

数据量都比较大,n和q都是10^5,但因为q次都是查询操作,并没有要求在线更新和查询,所以我们想到用离线算法,先把全部的输入接收,然后离线算出最后打出结果。

这题的思路是把所有的建筑物按照高度从大到小排序,然后所有的查询按照x从小到大排序,然后用建筑物去更新每个人一个建筑物只能更新一个人的一边的角度,当不能更新时,则推出此次更新,取出下一个建筑物来更新所有的人。理论上这样到后面每个建筑物可以更新的人的数量会越来越少,所以不会超时。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn = 100005;
const double PI = acos(-1.0);
struct node
{
double x,h;
}building[maxn];
struct Node
{
double x,left,right;
int ci;
}men[maxn];
bool cmpb(node a,node b)
{
if(a.h != b.h)
return a.h > b.h;
else return a.x  < b.x;
}
bool cmpm(Node a,Node b)
{
return a.x < b.x;
}
bool cmpci(Node a,Node b)
{
return a.ci < b.ci;
}
int find(double x,int l,int r)
{
while(l < r)
{
int mid = (l + r) >> 1;
if(men[mid].x >= x)
r = mid;
else l = mid + 1;
}
return l;
}

double zhuanhua(double a,double b)
{
double temp = PI - (atan(a) + atan(b));
temp = 180.0 * temp / PI;
return temp;
}
int main()
{
int T,kase = 1,n,q;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i = 1;i <= n;++i)
scanf("%lf%lf",&building[i].x,&building[i].h);
scanf("%d",&q);
for(int i  = 1;i <= q;++i)
{
scanf("%lf",&men[i].x);
men[i].ci = i;
men[i].left = men[i].right = 0;
}
sort(building+1,building+n+1,cmpb);
sort(men+1,men+q+1,cmpm);
for(int i = 1;i <= n;++i)
{
int m = find(building[i].x,1,q+1);    //第 m 个是第一个大于这个 x 的位置
//        printf("m = %d\n",m);
//////现在先往右扫
int r = m;
while(r <= q)
{
double k = building[i].h / (men[r].x - building[i].x);
if(k > men[r].right)
men[r++].right = k;
else break;
}
int l = m - 1;
while(l >= 1)
{
double k = building[i].h / (building[i].x - men[l].x);
if(k > men[l].left)
men[l--].left = k;
else break;
}
}
sort(men+1,men+q+1,cmpci);
printf("Case #%d:\n",kase++);
for(int i = 1;i <= q;++i)
printf("%.10lf\n",zhuanhua(men[i].left,men[i].right));
}
return 0;
}
/*
33
5
1 2
3 3
5 1
7 4
9 2
4
2
4
6
8
*/


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: