一 问题描述

设有 n 家客户,n <= 24,每个客户有如下属性(客户名称、客户类型、经度、纬度、每月拜访次数)。

每个客户 m 天拜访 1 次。

每个客户每天最多拜访 8 次。

给出一个月的工作日列表。

求一个月拜访轨迹。

二 输入和输出

1 输入说明

第 1 行代表客户数 n 和拜访频率 m。

接下来的 n 行描述每个客户,每个客户信息包括(客户名称、客户类型、经度、纬度、每月拜访次数),客户类型有:M-商业拜访,H-医院拜访、P-药房拜访

接下来的一行是工作日列表

2 输出说明

药代这个月每天拜访轨迹。

三 输入和输出样例

1 输入样例

24 3

H1 H 117.196067 39.103303 8

H2 H 117.206175 39.111509 8

H3 H 117.187551 39.109744 8

H4 H 117.179981 39.113295 8

H5 H 117.183536 39.125713 8

H6 H 117.209626 39.12228 8

H7 H 117.233087 39.082267 8

H8 H 117.195568 39.111846 8

H9 H 117.207421 39.121483 8

H10 H 117.191717 39.104914 8

H11 H 117.200753 39.109458 8

H12 H 117.182597 39.102957 8

H13 H 117.188228 39.128191 8

H14 H 117.193003 39.121008 8

H15 H 117.190858 39.135014 8

H16 H 117.179979 39.11038 8

M1 B 117.18461 39.117381 4

M2 B 117.206176 39.127932 4

M3 B 117.185073 39.124452 4

M4 B 117.183584 39.121472 4

M5 B 117.172522 39.126702 4

M6 B 117.185248 39.104909 4

M7 B 117.192618 39.129049 4

M8 B 117.181509 39.123574 4

1 2 3 4 5 7 8 9 10 11 12 14 15 16 17 18 19 21 22 23 24 25 26 28 29 30

2 输出样例

1 号拜访客户:H9 > H6 > M2 > H15 > M8 > M5 > H3 > H12 >

2 号拜访客户:H4 > H16 > M6 > H10 > H1 > M3 > H13 > H7 >

3 号拜访客户:M7 > H5 > M4 > M1 > H14 > H8 > H11 > H2 >

4 号拜访客户:M2 > H6 > H9 > H15 > M8 > M5 > H3 > H12 >

5 号拜访客户:H1 > H10 > M6 > H16 > H4 > M3 > H13 > H7 >

7 号拜访客户:H14 > M4 > M1 > H5 > M7 > H8 > H11 > H2 >

8 号拜访客户:H15 > M8 > M5 > H3 > H12 > H9 > H6 > M2 >

9 号拜访客户:H7 > H1 > H10 > M6 > H16 > H4 > M3 > H13 >

10 号拜访客户:H5 > M4 > M1 > H14 > M7 > H8 > H11 > H2 >

11 号拜访客户:H12 > H3 > M8 > M5 > H15 > M2 > H6 > H9 >

12 号拜访客户:H7 > H1 > H10 > M6 > H16 > H4 > M3 > H13 >

14 号拜访客户:H8 > H11 > H2 > H14 > M4 > M1 > H5 > M7 >

15 号拜访客户:H6 > H9 > H15 > H3 > H12 >

16 号拜访客户:H7 > H1 > H10 > H16 > H4 > H13 >

17 号拜访客户:H8 > H11 > H2 > H14 > H5 >

18 号拜访客户:H3 > H12 > H9 > H6 > H15 >

19 号拜访客户:H16 > H4 > H10 > H1 > H13 > H7 >

21 号拜访客户:H8 > H11 > H2 > H14 > H5 >

22 号拜访客户:H9 > H6 > H15 > H3 > H12 >

23 号拜访客户:H13 > H4 > H16 > H10 > H1 > H7 >

24 号拜访客户:H5 > H14 > H8 > H11 > H2 >

25 号拜访客户:H3 > H12 > H9 > H6 > H15 >

26 号拜访客户:H4 > H16 > H10 > H1 > H13 > H7 >

28 号拜访客户:H8 > H11 > H2 > H14 > H5 >

四 代码

package com.platform.modules.alg.alglib.sdgt0002;import java.util.*;public class Sdgt0002 {public String output = "";/*** 默认地球半径*/private static double EARTH_RADIUS = 6371000; // 赤道半径(单位m)private final int inf = 0x3f3f3f3f;// 客户数private int n;// 拜访频率,几天拜访一次private int frequency;// 拜访天数,每月拜访多少天private int days;// 客户批次 map,第1个泛型代表第几批客户,第2个泛型代表批次客户列表private Map<Integer, List<Customer>> batchCustomerMap = new HashMap<>();// 拜访轨迹 map,第1个泛型代表每月第几天,第2个泛型代表该天拜访的客户列表private Map<Integer, List<Customer>> visitMap = new HashMap<>();// 轨迹计算public String cal(String input) {String[] line = input.split("\n");String[] params = line[0].split(" ");n = Integer.parseInt(params[0]); // 客户数frequency = Integer.parseInt(params[1]); // 几天拜访一次//days = Integer.parseInt(params[2]); // 每月拜访多少天// 对输入数据进行处理for (int i = 1; i <= n; i++) {String[] customerStr = line[i].split(" ");Customer customer = new Customer();customer.setName(customerStr[0]); // 客户名称customer.setType(customerStr[1]); // 客户类别customer.setLocationLon(Double.parseDouble(customerStr[2])); // 经度customer.setLocationLat(Double.parseDouble(customerStr[3])); // 纬度customer.setTotalCount(Integer.parseInt(customerStr[4])); // 每月最多拜访次数// 批次客户列表加第1个客户,如果 frequency = 3,则批次下标范围 [0,1,2]if (batchCustomerMap.get(i % frequency) == null) {List<Customer> batchCustomerList = new ArrayList();batchCustomerList.add(customer);batchCustomerMap.put(i % frequency, batchCustomerList);} else { // 批次客户列表加其他客户batchCustomerMap.get((i % frequency)).add(customer);}}// 模拟每月的几号String[] days = line[n + 1].split(" ");List batchDays[] = new ArrayList[frequency];for (int i = 0; i < batchDays.length; i++) {batchDays[i] = new ArrayList();}for (int i = 0; i < days.length; i++) {int batchNum = i % frequency;batchDays[batchNum].add(days[i]);}// 每日拜访处理for (int i = 0; i < days.length; i++) {int batch = 0;for (List batchDay : batchDays) {if (batchDay.contains(days[i])) {batch = i % frequency;break;}}// 获取某批次客户列表List<Customer> customers = batchCustomerMap.get(batch);// 打乱批次客户列表顺序Collections.shuffle(customers);List<Customer> selectCustomers = new ArrayList<>();// 选择前8个客户for (int j = 0; j < customers.size(); j++) {if (customers.get(j).getTotalCount() > 0) {selectCustomers.add(customers.get(j));if (selectCustomers.size() >= 8) {break;}}}// 每日拜访的第1个客户if (selectCustomers.size() == 0) continue;Customer startCustomer = selectCustomers.get(0);// 标识该客户已访问startCustomer.setVisited(true);// 修正剩余可拜访次数int plusCount = startCustomer.getTotalCount() - 1;startCustomer.setTotalCount(plusCount);// 创建第 i 号的拜访客户列表List<Customer> oneDayCustomerList = new ArrayList();visitMap.put(i, oneDayCustomerList);// 向 i 号拜访客户列表加第1个客户oneDayCustomerList.add(startCustomer);Customer firstCustomer; // 两次相邻拜访的前一个客户Customer secondCustomer; // 两次相邻拜访的后一个客户Customer nextSelectCustomer = new Customer(); // 下一个选中的客户double tempMinDistance; // 临时最短距离firstCustomer = startCustomer;for (int m = 1; m < selectCustomers.size(); m++) { // 从第2个客户开始处理double minDistance = inf; // 初始化最短距离for (int n = 1; n < selectCustomers.size(); n++) { // 从第2个客户开始处理secondCustomer = selectCustomers.get(n);// 两次相邻拜访的后一个客户如果已经拜访或剩余可拜访次数为0,不处理if (secondCustomer.isVisited() || secondCustomer.getTotalCount() == 0) {continue;}// 计算相邻两个客户的距离tempMinDistance = GetDistance(firstCustomer.getLocationLon(), firstCustomer.getLocationLat(), secondCustomer.getLocationLon(), secondCustomer.getLocationLat());if (tempMinDistance < minDistance) {// 更新最短距离minDistance = tempMinDistance;// 最短距离对应的客户nextSelectCustomer = secondCustomer;}}// 下一个被选中的客户设置为已拜访nextSelectCustomer.setVisited(true);int plusTimes = nextSelectCustomer.getTotalCount() - 1;// 下一个被选中的客户剩余拜访次数nextSelectCustomer.setTotalCount(plusTimes);// 向 i 号拜访客户列表加选中的客户visitMap.get(i).add(nextSelectCustomer);firstCustomer = nextSelectCustomer;}// visited 只对当天拜访起作用,所以要清空 visited 标识for (Customer selectCustomer : customers) {selectCustomer.setVisited(false);}}// 输出处理for (int i = 0; i < days.length; i++) {List<Customer> customers = visitMap.get(i);if (customers == null) {continue;}output += days[i] + " 号拜访客户:";for (Customer customer : customers) {output += customer.getName() + " > ";}output += "\n";}return output;}/*** 功能描述:通过经纬度计算两点之间的距离** @param lon1 第 1 个点的经度* @param lat1 第 1 个点的纬度* @param lon2 第 2 个点经度* @param lat2 第 2 个点纬度* @return 两点间的距离* @author chengqiuming* @date 2022/10/25* @description:*/public double GetDistance(double lon1, double lat1, double lon2, double lat2) {double radLat1 = rad(lat1);double radLat2 = rad(lat2);double a = radLat1 - radLat2;double b = rad(lon1) - rad(lon2);double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));s = s * EARTH_RADIUS;s = Math.round(s * 10000) / 10000;return s;}/*** 转化为弧度(rad)*/private static double rad(double d) {return d * Math.PI / 180.0;}
}class Customer {// 客户名称private String name;// 客户类型 H-医院客户 M-商业公司客户 P-药房拜访private String type;// 经度private Double locationLon;// 纬度private Double locationLat;// 每月最多可拜访次数private int totalCount;// 是否已拜访private boolean visited = false;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getType() {return type;}public void setType(String type) {this.type = type;}public Double getLocationLon() {return locationLon;}public void setLocationLon(Double locationLon) {this.locationLon = locationLon;}public Double getLocationLat() {return locationLat;}public void setLocationLat(Double locationLat) {this.locationLat = locationLat;}public int getTotalCount() {return totalCount;}public void setTotalCount(int totalCount) {this.totalCount = totalCount;}public boolean isVisited() {return visited;}public void setVisited(boolean visited) {this.visited = visited;}
}

五 测试

1 输入

24 3

H1 H 117.196067 39.103303 8

H2 H 117.206175 39.111509 8

H3 H 117.187551 39.109744 8

H4 H 117.179981 39.113295 8

H5 H 117.183536 39.125713 8

H6 H 117.209626 39.12228 8

H7 H 117.233087 39.082267 8

H8 H 117.195568 39.111846 8

H9 H 117.207421 39.121483 8

H10 H 117.191717 39.104914 8

H11 H 117.200753 39.109458 8

H12 H 117.182597 39.102957 8

H13 H 117.188228 39.128191 8

H14 H 117.193003 39.121008 8

H15 H 117.190858 39.135014 8

H16 H 117.179979 39.11038 8

M1 B 117.18461 39.117381 4

M2 B 117.206176 39.127932 4

M3 B 117.185073 39.124452 4

M4 B 117.183584 39.121472 4

M5 B 117.172522 39.126702 4

M6 B 117.185248 39.104909 4

M7 B 117.192618 39.129049 4

M8 B 117.181509 39.123574 4

1 2 3 4 5 7 8 9 10 11 12 14 15 16 17 18 19 21 22 23 24 25 26 28 29 30

2 输出

1 号拜访客户:H15 > M8 > M5 > H3 > H12 > H9 > H6 > M2 >

2 号拜访客户:H1 > H10 > M6 > H16 > H4 > M3 > H13 > H7 >

3 号拜访客户:H14 > M4 > M1 > H5 > M7 > H8 > H11 > H2 >

4 号拜访客户:M2 > H6 > H9 > H15 > M8 > M5 > H3 > H12 >

5 号拜访客户:H13 > M3 > H4 > H16 > M6 > H10 > H1 > H7 >

7 号拜访客户:H14 > M4 > M1 > H5 > M7 > H8 > H11 > H2 >

8 号拜访客户:H6 > H9 > M2 > H15 > M8 > M5 > H3 > H12 >

9 号拜访客户:M3 > H13 > H4 > H16 > M6 > H10 > H1 > H7 >

10 号拜访客户:M1 > M4 > H5 > M7 > H14 > H8 > H11 > H2 >

11 号拜访客户:M8 > M5 > H15 > M2 > H6 > H9 > H3 > H12 >

12 号拜访客户:M3 > H13 > H4 > H16 > M6 > H10 > H1 > H7 >

14 号拜访客户:H8 > H11 > H2 > H14 > M4 > M1 > H5 > M7 >

15 号拜访客户:H15 > H9 > H6 > H3 > H12 >

16 号拜访客户:H7 > H1 > H10 > H16 > H4 > H13 >

17 号拜访客户:H5 > H14 > H8 > H11 > H2 >

18 号拜访客户:H12 > H3 > H9 > H6 > H15 >

19 号拜访客户:H1 > H10 > H16 > H4 > H13 > H7 >

21 号拜访客户:H11 > H2 > H8 > H14 > H5 >

22 号拜访客户:H9 > H6 > H15 > H3 > H12 >

23 号拜访客户:H4 > H16 > H10 > H1 > H13 > H7 >

24 号拜访客户:H2 > H11 > H8 > H14 > H5 >

25 号拜访客户:H12 > H3 > H9 > H6 > H15 >

26 号拜访客户:H1 > H10 > H16 > H4 > H13 > H7 >

28 号拜访客户:H11 > H2 > H8 > H14 > H5 >

基于经纬度和工作日的拜访轨迹问题相关推荐

  1. 基于经纬度的拜访轨迹问题

    一 问题描述 设有 n 家客户,n<=31,每个客户有如下属性(客户名称.客户类型.经度.纬度.每月拜访次数). 每个客户 times 天拜访 1 次. 每个客户每天最多拜访 8 次. 每月天数 ...

  2. 一种基于贝塞尔曲线的终端定位轨迹拟合方法

    一种基于贝塞尔曲线的终端定位轨迹拟合方法 专利名称一种基于贝塞尔曲线的终端定位轨迹拟合方法 技术领域本发明属于卫星导航领域,具体涉及一种基于贝塞尔曲线的终端定位轨迹拟合方法. 背景技术目前有很多设备( ...

  3. 【手机信令轨迹挖掘01】基于手机信令的用户出行轨迹挖掘之问题定义

    手机信令数据 手机信令数据是指移动终端用户在发生通话.短信.上网及变换寻呼区时在运营商网络中产生的大量手机信令数据. 手机信令数据直接来源于运营商(中国移动.中国联通.中国电信)的移动通信系统,通常对 ...

  4. matlab机器人轨迹规划仿真程序,基于MATLAB的六自由度机器人轨迹规划与仿真.pdf...

    基于MATLAB的六自由度机器人轨迹规划与仿真 学兔兔 l 訇 似 基于MATLAB的六自由度机器人轨迹规划与仿真 Trajectory planning and simulation of six- ...

  5. 基于hyperledger联盟链的汽车轨迹追溯系统 (三)

    基于hyperledger联盟链的汽车轨迹追溯系统 一.后端接口搭建 引入模块 插入轨迹完整流程 区块链验证 封装区块信息查询 查询 二.配置路由 三.简单的测试调用 四.个性化的业务功能 一.后端接 ...

  6. mysql数据范围什么意思_数据都在mysql里的话,基于经纬度的范围查询有什么高效的方案吗...

    [今日话题] 数据都在mysql里的话,基于经纬度的范围查询有什么高效的方案吗 – yingang 1. 经纬度搜索(1)-Geohash算法原理 http://hankesi2000.iteye.c ...

  7. 《整体决策的统一框架和基于时空的高速路自动驾驶轨迹规划》论文分析

    文献分析 这篇<整体决策的统一框架和基于时空的高速路自动驾驶轨迹规划>论文,针对过往前任研究的一些不足,建立了决策规划的三个模块,这三个模块针对短期(10hz,一秒运行十次),中期(1hz ...

  8. 【K-Means】基于经纬度的城市聚类

    文章目录 1. 项目准备 1.1. 问题导入 1.2. 数据集简介 2. K-Means算法 2.1. 算法特点 2.2. 算法流程 2.3. 算法缺陷 2.4. 算法改进 3. 实验步骤 3.1. ...

  9. 轨迹跟踪主要方法_DELMIA教程:基于指令形式的机器人TCP轨迹局部跟踪方法

    上一期为大家介绍了基于工具条中的"TCP Trace"命令按钮的全局TCP轨迹跟踪,之所以称之为全局轨迹跟踪,是因为只要命令被打开,机器人运行的全部轨迹都将实现跟踪.既然有全局TC ...

最新文章

  1. 爱的世界很拥挤,写在读《爱,就这么简单》之后
  2. 【Git、GitHub、GitLab】十 将git仓库备份到本地
  3. java数学函数Math类
  4. 事件---------2
  5. pyGurobi使用手册
  6. 18年12月英语六级第二套听力单词
  7. jscpd--前端代码重复率检测
  8. “分类” 与 “回归”的概念及区别详解
  9. mac 恢复未能与服务_MacBook Pro无法与恢复服务器取得联系?
  10. 小程序关注微信公众号的方法
  11. 如何减少PDF文件的大小,为pdf瘦身?
  12. Ubuntu下使用OpenCV显示中文
  13. Sieve of Eratosthenes(埃拉托色尼筛选法)——C++实现
  14. 搜索引擎蜘蛛抓取不到网站内容页面的原因总结
  15. LaTeX入门|(2)定制专属模板
  16. 中国宽带无线移动互联网论坛-无线传感器网络
  17. nvidia jetson nano 操作指南
  18. LocalDate获取本日所在周的周一和周日
  19. 交换机千兆和百兆对网速影响_千兆网线和百兆网线是否可以通用?
  20. 移动端H5(JavaScript)识别二维码功能

热门文章

  1. ZigBee 3.0教程 - 从头开始Light和Switch
  2. 在浙江大学做全校单点登录接入的心得体会,采用sun公司的单点登录技术
  3. 【华为机试真题Java】统计射击比赛成绩
  4. 03-03 创建和编辑AutoCAD实体(三) 使用选择集(2)
  5. Python爬虫学习之路(1)--前端
  6. JS 输出指定格式的时间
  7. Krpano 全景图简单制作
  8. 苹果电脑拷贝文件到u盘很慢_U盘防拷贝哪家比较好?哪个做得好?
  9. 字节跳动2019春招研发机试题  万万没想到之聪明的编辑
  10. Boss直聘网requests多进程爬虫,写入Mysql