您的位置:首页 > 编程语言

CodingTrip - 携程编程大赛 (预赛第一场)

2014-04-15 21:12 232 查看



携程全球数据中心建设

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 725    Accepted Submission(s): 307


Problem Description

携程为了扩展全球在线旅游业务,决定在全球建设多数据中心,以便提高网站的访问速度和容灾处理。
为了实现每个数据中心的数据能互通,数据中心之间需要通过光纤连接。为了节约光纤成本,我们计划采用点对点方式来达到最终各个数据中心的数据互通,每个数据中心本身都可以作为数据中转站。做为全球多数据中心设计者,您需要知道最短的光纤总长度,来把所有的数据中心都实现互通。假设地球是个圆球,且表面是平滑的,并且没有任何阻碍物(河流,山脉)。

输入数据是一组数据中心的经纬度
纬度: -90° 到 +90°
经度: -180° 到 +180°
(圆周率pi= 3.14159265358979323846)

 

Input

第一行第一个整数N(1≤N≤100),表示有多少个用例. 每个用例包含了:
第一行,小数D(1≤D≤1,000,000),表面圆球的直径(公里).
第二行,小数L(1≤L≤1,000,000) 光纤总长度 (公里).
第三行,整数C(1≤C≤100) ,表示数据中心的数量.
接下来的C行, 每行有2个形如"X Y"的小数,表示每个数据中心的纬度(-90≤X≤90)和经度 (-180≤Y≤180).

 

Output

每个用例输出一行. 如果光纤长度L足够连接所有数据中心,输出"Y", 否则输出"N"。

 

Sample Input

2
12742
5900
3
51.3 0
42.5 -75
48.8 3
12742
620
2
30.266 97.75
30.45 91.1333

 

Sample Output

Y
N

给你 C个地球上的点,给你他们的经纬度 , 求一下他们的MST,检验是否在 给定的限制长度内。

把这个题目记录下来 主要是因为  自己半天没有推算出来 给定两点的 经纬度 和地球半径 求两点间的弧的长度或者 夹角 的 公式。。就在网上找了下。。

剩下的就是最小生成树的 套用了。

CODE:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include<cmath>
using namespace std;
#define INF 1000000000
#define PI acos(-1.0)
#define N 105
int n,c,ss,par
;
double d,l;
struct node
{
double x,y;
int id;
}point
;
struct no
{
int u,v;
double w;
}edge[N*N];
int cmp(no a,no b)
{
return a.w<b.w;
}
int fi(int x)
{
if(x!=par[x]) par[x]=fi(par[x]);
return par[x];
}
double rad(double x)
{
return x*PI/180.0;
}
double kru()
{
double ret=0;
int cou=0;
for(int i=1;i<=ss;i++)
{
int u=edge[i].u;
int v=edge[i].v;
int x=fi(u);
int y=fi(v);
if(x!=y)
{
par[y]=x;
cou++;
ret+=edge[i].w;
if(cou>=c-1) return ret;
}
}
return INF;
}
double get_dis(double x1,double y1,double x2,double y2)
{
double radx1=rad(x1);
double radx2=rad(x2);
double a=radx1-radx2;
double b=rad(y1)-rad(y2);
double ret=2*asin(sqrt(sin(a/2)*sin(a/2) + cos(radx1)*cos(radx2)*sin(b/2)*sin(b/2)));
return d*ret/2.0;
}
int main()
{
scanf("%d",&n);
while(n--)
{
scanf("%lf",&d);
scanf("%lf",&l);
scanf("%d",&c);
for(int i=1;i<=c;i++)
{
scanf("%lf%lf",&point[i].x,&point[i].y);
point[i].id=i;
}
ss=0;
for(int i=0;i<=c;i++) par[i]=i;
for(int i=1;i<=c;i++)
{
for(int j=i+1;j<=c;j++)
{
double tmp=get_dis(point[i].x,point[i].y,point[j].x,point[j].y);
edge[++ss].w=tmp;
edge[ss].u=i; edge[ss].v=j;
}
}
sort(edge+1,edge+1+ss,cmp);
double ans=kru();
if(ans<=l) puts("Y");
else puts("N");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: