这是 meelo 原创的 IEEEXtreme极限编程大赛题解

Xtreme10.0 - Food Truck

题目来源 第10届IEEE极限编程大赛

https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/food-truck

Madhu has a food-truck called "The Yummy Goods" that goes to a different business hotspot every day at lunch! Madhu wants to perform location-based advertising to folks in the offices near her halt. To do this she uses the GPS location as a longitude and a latitude at the stop and decides on a radius (r) value. She wants to broadcast advertisement SMSes, to customers within this radius, advertising her food-truck.

She needs your help to generate the list of phone numbers of such folks. She has access to a big file of telecom data, which among other details, contains the phone number, longitude and latitude of active cell-phone users in the city at that moment.

In order to calculate the distance between her stops and her subscribers, she wants you to use the most recent location available for each subscriber. To calculate the distance, you should use the Haversine formula:

d = 2 × r × arcsin (sqrt (sin2((lat1 - lat2)/2) + cos(lat1) × cos(lat2) × sin2((long1 - long2)/2)))

where d is the distance between two points on the surface of the earth, in km's

r is the radius of the earth (6378.137 km for this problem)

lat1long1 are the latitude and longitude, respectively, of point 1

lat2long2 are the latitude and longitude, respectively, of point 2

Input Format

The first line contains Madhu's latitude and longitude in degrees, separated by a comma.

The second line contains the radius r in kms, within which she wants to broadcast her advertisement.

The third line is a header for the data in the subsequent lines.

The remaining lines have rows of telecom data of active cellphone users. Each line contains the following comma-separated fields:

  • A time stamp in MM/DD/YYYY hh:mm format. MM, is a two-digit month, e.g. 01 for January, DD is a two-digit day of month (01 through 31), YYYY is a four-digit year, hh is the two digits of hour (00 through 23), and mm is the two digits of minute (00 through 59)

  • The latitude of the subscriber, in degrees

  • The longitude of the subscriber, in degrees

  • The subscriber's phone number, as a 10-digit number

Notes:

  • Some subscribers may appear multiple times. You should use the most recent entry to determine the location and phone number of a subscriber. If a subscriber appears multiple times, the date/time stamps will differ.

  • None of the field values will contain commas.

Constraints

In order to eliminate rounding and approximation errors, no subscribers will be at a distance d from Madhu, such that 0.99 × r ≤ d ≤ 1.01 × r

1 ≤ r ≤ 100

There will be at most 50,000 lines in the subscriber list.

Output Format

A comma separated list of phone numbers for subscribers within a radius r of the stop, sorted in ascending order.

Sample Input

18.9778972,72.8321983
1.0
Date&Time,Latitude,Longitude,PhoneNumber
10/21/2016 13:34,18.912875,72.822318,9020320100
10/21/2016 10:35,18.9582233,72.8275845,9020320024
10/21/2016 15:20,18.95169982,72.83525604,9020320047
10/21/2016 15:23,18.9513048,72.8343388,9020357980
10/21/2016 15:23,18.9513048,72.8343388,9020357962
10/21/2016 15:28,18.9548652,72.8332443,9020320027
10/21/2016 14:03,18.9179784,72.8279306,9020357972
10/21/2016 14:03,18.9179784,72.8279306,9020357959
10/21/2016 09:52,18.97523123,72.83494895,9020320007
10/21/2016 09:44,18.9715932,72.8383992,9020357607
10/21/2016 09:44,18.9715932,72.8383992,9020357593
10/21/2016 09:44,18.9715932,72.8383992,9020357584
10/21/2016 14:57,18.93438826,72.82704499,9020320011
10/21/2016 09:56,18.97596514,72.8327072,9020320045
10/21/2016 08:33,18.9811929,72.8353202,9020320084
10/21/2016 13:27,18.9159265,72.8245989,9020357896
10/21/2016 13:09,18.9077347,72.8076201,9020320094
10/21/2016 10:52,18.97523003,72.83494865,9020320007

Sample Output

9020320007,9020320045,9020320084,9020357584,9020357593,9020357607

Explanation

We can calculate the distance between the location "18.9778972, 72.8321983" and each of the subscribers whose details are provided. Only the 6 phone numbers, listed in the Sample Output set, have a distance to the location of the food-truck that is less than 1.0 km.

题目解析

题目本身并没什么难的,但有几个地方容易犯错误。

几个注意事项:

  • 首先Haversine公式里的经纬度是弧度、而输入的数据单位是角度,需要进行转换。
  • 不要忘了所有的经纬度都要转换,包括店铺的位置和客户的位置。
  • 读入数据用scanf比cin要容易一些。
  • 可以创建一个结构体来保存用户的数据,key为电话号码。
  • 输出的升序是电话号码的升序。
  • 读取行数不确定的输入,可以用while(scanf(...) != EOF)
  • 比较时间的前后关系,可以先把时间转换成一个数,转换过程中可以把每个月都算31天,每年都算366天。

程序

C++

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <map>
#include <string> #define PI 3.1415926 using namespace std; struct Custom {
int year, month, day, hour, minute, second;
double lat, long_; int timeNumber() const {
return second + minute* + hour* + day*
+ month* + (year-)*;
} bool earlyThan(const Custom & that) {
return timeNumber() < that.timeNumber();
} bool inRange(double r, double myLat, double myLong) const {
double d = * 6378.137 * asin (sqrt ( pow(sin((lat-myLat)/),) + cos(lat) * cos(myLat) * pow(sin((long_-myLong)/),)));
return d < r;
}
}; double degree2radian(double degree) {
return degree / * PI;
} int main() {
double myLat, myLong, r; scanf("%lf,%lf", &myLat, &myLong);
myLat = degree2radian(myLat);
myLong = degree2radian(myLong); scanf("%lf", &r);
map<long long, Custom> customs; string ignore;
cin >> ignore; Custom c;
long long phone;
while(scanf("%d/%d/%d %d:%d,%lf,%lf,%lld", &c.day, &c.month, &c.year, &c.hour, &c.minute, &c.lat, &c.long_, &phone) != EOF) {
c.lat = degree2radian(c.lat);
c.long_ = degree2radian(c.long_);
if(customs.find(phone) == customs.end()) {
customs[phone] = c;
}
else {
if(customs[phone].earlyThan(c)) {
customs[phone] = c;
}
}
c = customs[phone];
} bool first = true;
for(const auto kv : customs) {
if( kv.second.inRange(r, myLat, myLong) ) {
if(!first) cout << ',';
first = false;
cout << kv.first;
}
} return ;
}

Python2

from datetime import datetime
from math import radians, cos, sin, asin, sqrt
import sys def haversine(lon1, lat1, lon2, lat2):
"""
Calculate the great circle distance between two points
on the earth (specified in decimal degrees)
"""
# convert decimal degrees to radians
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) # haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
r = 6378.137
return c * r lat, lon = map(float, raw_input().split(","))
r = float(raw_input())
raw_input()
d = {}
d = {}
for line in sys.stdin:
subscriber = line.strip().split(",") dat = datetime.strptime(subscriber[0], "%m/%d/%Y %H:%M")
h = haversine(lon, lat, float(subscriber[2]), float(subscriber[1]))
if subscriber[3] in d:
if dat > d[subscriber[3]][0]:
d[subscriber[3]] = [dat, h]
else:
d[subscriber[3]] = [dat, h]
res = []
for phone in d:
if d[phone][1]<=r:
res.append(phone) print ",".join([phone for phone in sorted(res)])

from: blog.chaker.tn/posts/food-truck-ieeextreme-10-0

博客中的文章均为 meelo 原创,请务必以链接形式注明 本文地址

IEEEXtreme 10.0 - Food Truck的更多相关文章

  1. IEEEXtreme 10.0 - Inti Sets

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Inti Sets 题目来源 第10届IEEE极限编程大赛 https://www.hackerrank.c ...

  2. IEEEXtreme 10.0 - Painter's Dilemma

    这是 meelo 原创的 IEEEXtreme极限编程比赛题解 Xtreme 10.0 - Painter's Dilemma 题目来源 第10届IEEE极限编程大赛 https://www.hack ...

  3. IEEEXtreme 10.0 - Ellipse Art

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Ellipse Art 题目来源 第10届IEEE极限编程大赛 https://www.hackerrank ...

  4. IEEEXtreme 10.0 - Counting Molecules

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Counting Molecules 题目来源 第10届IEEE极限编程大赛 https://www.hac ...

  5. IEEEXtreme 10.0 - Checkers Challenge

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Checkers Challenge 题目来源 第10届IEEE极限编程大赛 https://www.hac ...

  6. IEEEXtreme 10.0 - Game of Stones

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Game of Stones 题目来源 第10届IEEE极限编程大赛 https://www.hackerr ...

  7. IEEEXtreme 10.0 - Playing 20 Questions with an Unreliable Friend

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Playing 20 Questions with an Unreliable Friend 题目来源 第1 ...

  8. IEEEXtreme 10.0 - Full Adder

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Full Adder 题目来源 第10届IEEE极限编程大赛 https://www.hackerrank. ...

  9. IEEEXtreme 10.0 - N-Palindromes

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - N-Palindromes 题目来源 第10届IEEE极限编程大赛 https://www.hackerra ...

随机推荐

  1. 【agc004F】Namori

    Portal -->agc004F Solution  好神仙的转化qwq ​  首先我们可以先考虑\(m=n-1\)的情况下,也就是树的情况下要怎么做  我们可以将这个问题转化一下:我们对这颗 ...

  2. 洛谷P2344 奶牛抗议

    题目背景 Generic Cow Protests, 2011 Feb 题目描述 约翰家的N 头奶牛正在排队游行抗议.一些奶牛情绪激动,约翰测算下来,排在第i 位的奶牛的理智度为Ai,数字可正可负. ...

  3. 服务器上 tomcat 配置了 tomcat-users 但是还是 403 的问题

    默认情况下,tomcat 限制了只能本机访问 如果我们想要修改这个设置: 编辑 webapps/manager/META-INF/context.xml <!--<Valve classN ...

  4. C++调用函数模仿数字钟表

    调用系统函数,可以得到系统时间 #include<iostream> #include<windows.h> #include<time.h> using name ...

  5. Highcharts.js -纯javasctipt图表库初体验

    一.highcharts简介以及引入 highcharts作为免费提供给个人学习.个人网站和非商业用途使用的前端图表演示插件的确使用起来十分方便和轻便.在我最近完成一个需求的时候用到了它, 它的兼容性 ...

  6. ubuntu如何杀死进程

    一.得到所有进程 先用命令查询出所有进程 ps -ef 二.杀死进程 我们使用ps -ef命令之后,就会得到一些列进程信息,有进程pid什么的,如果你要杀死莫个进程的话,直接使用命令   kill   ...

  7. 前端PHP入门-032-异常处理-应用级别

    禁止显示错误 在php.ini配置文件中.我们可以控制php的错误显示状态. php.ini中有一个专门的配置项: display_errors 这个选项设置是否将错误信息输出到网页,或者对用户隐藏而 ...

  8. 分块基础练习 UESTC 1324

    http://acm.uestc.edu.cn/#/problem/show/1324 思路:基础分块,这个是一个特别简单的分块,就当做是一个练习了.然后这题也是很简单的单点线段树更新. //看看会不 ...

  9. 「七天自制PHP框架」第一天:路由与控制器

    我们为什么要使用路由? 原因1:一个更漂亮的URI 1.URI的改进 刚刚开始学PHP时,我们一定写过blog.php?id=1之类的URI,使用GET方式获取参数.这样的URI有两个缺点,一是容易被 ...

  10. $this->success()传值不完整

    public function manager_doExport() { $search=$_POST['search']; //前台输入2017-12-1,即,$search['starttime' ...