Xtreme 10.0 - Food Truck
题目:
https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/food-truck
题意:
Madhu是一个食品商,为了增加生意收入,他决定向附近的客户派发广告。给定Madhu所处位置的经纬度、派发广告的半径范围、以及周围客户的通讯信息(客户通讯信息包括:时间戳、经纬度以及电话号码)。替Madhu写一个程序,帮助Madhu挑选出与与其相对位置的距离小于所设半径范围的所有客户的电话号码。
注意:
1、其中同一个客户可能在不同时间段出现在不同的地点,此时以该客户的最新时间为位置为基准。
2、距离的计算公式为:d = 2 × r × arcsin (sqrt (sin2((lat1 - lat2)/2) + cos(lat1) × cos(lat2) × sin2((long1 - long2)/2)))。其中d表示两点间的距离,单位是千米;r表示地球的半径,取值为6378.137千米;lat1,long1表示第一个点的经纬度;lat2,long2表示第二个点的经纬度。
输入:
第一行的两个数表示Madhu位置的经纬度,用逗号隔开。
第二行为所设定派送广告的半径范围,单位为千米,范围为[1, 100]。
第三行为客户通讯信息的标题部分。
接下来的n行是客户通讯信息,包括时间戳(格式为MM/DD/YYYY hh:mm)、经纬度(角度值)、客户电话号码(10个数字)。通讯信息最多不超过1000行。
测试用例:
输入:
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
输出:
9020320007,9020320045,9020320084,9020357584,9020357593,9020357607
思路:
代码:
#include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
#define M_PI 3.1415926535898
class Item {
public:
double latitude;
double longitude;
long long PhoneNumber;
time_t time;
string timeStr;
Item(string s) {
unsigned int sp = s.find_first_of(',');
string tStr(s.begin(), s.begin() + sp);
timeStr = tStr;
time = getTimeByStr(tStr);
string tmp(s.begin() + sp + 1, s.end());
int sp1 = tmp.find_first_of(',');
int sp2 = tmp.find_last_of(',');
string s1(tmp.begin(), tmp.begin() + sp1);
string s2(tmp.begin() + sp1 + 1, tmp.begin() + sp2);
string s3(tmp.begin() + sp2 + 1, tmp.end());
latitude = stod(s1);
longitude = stod(s2);
PhoneNumber = stoll(s3);
}
private:
time_t getTimeByStr(string s) {
tm time;
//10/21/2016 13:34
sscanf(s.c_str(), "%d/%d/%d %d:%d",
&time.tm_mon, &time.tm_mday, &time.tm_year,
&time.tm_hour, &time.tm_min);
time.tm_year -= 1900;
time.tm_mon -= 1;
time.tm_sec = 0;
time_t res = mktime(&time);
return res;
}
};
double distanceBetween(double lat1, double longt1, double lat2, double longt2) {
lat1 = lat1 * M_PI / 180;
lat2 = lat2 * M_PI / 180;
longt1 = longt1 * M_PI / 180;
longt2 = longt2 * M_PI / 180;
double tmp1 = pow(sin((lat1 - lat2) / 2 ), 2);
double tmp2 = pow(sin((longt1 - longt2) / 2), 2);
double tmp3 = tmp1 + cos(lat1) * cos(lat2) * tmp2;
double tmp4 = sqrt(tmp3);
double r = 6378.137;
return 2 * r * asin(tmp4);
}
bool lessThan(const Item &item1, const Item &item2) {
if (item1.PhoneNumber < item2.PhoneNumber) return true;
else if (item1.PhoneNumber > item2.PhoneNumber) return false;
else if (item1.PhoneNumber == item2.PhoneNumber) {
if (item1.time > item2.time) return true;
else return false;
}
return false;
}
void upDateMap(unordered_map<long long, Item> &items, const Item &item) {
unordered_map<long long, Item>::iterator got = items.find(item.PhoneNumber);
if (got != items.end() && got->second.time < item.time) {
items.erase(got);
}
items.insert(pair<long long, Item>(item.PhoneNumber, item));
return;
}
void foodTruck() {
double lat = 0.0, lon = 0.0;
//cin >> lat >> lon;
scanf("%lf,%lf", &lat, &lon);
double aimDist = 0.0;
cin >> aimDist;
string inStr;
getchar();
getline(cin, inStr);
unordered_map<long long, Item> items;
while (1) {
getline(cin, inStr);
if (cin.eof()) break;
Item item(inStr);
upDateMap(items, item);
}
vector<Item> res;
for (unordered_map<long long, Item>::iterator it = items.begin();
it != items.end(); it++) {
Item item = it->second;
double distance = distanceBetween(lat, lon, item.latitude, item.longitude);
if (distance < aimDist) {
res.push_back(item);
}
}
sort(res.begin(), res.end(), lessThan);
for (vector<Item>::iterator it = res.begin(); it != res.end(); it++) {
if (it != res.begin() && (*it).PhoneNumber == (*(it - 1)).PhoneNumber) continue;
if (it != res.end() - 1) cout << (*it).PhoneNumber << ',';
else cout << (*it).PhoneNumber << endl;
}
}
int main() {
foodTruck();
return 0;
}