【NC50937】货仓选址

题目

货仓选址

二分,前缀和,数学推导

思路

由题意可知货仓的位置是可以和商店的位置重合的。首先应该将商店的坐标从小到大排序,然后假设商店的坐标为 a i a_i ai,货仓的坐标为 x x x,货仓左侧第一家商店(可能和货仓重合)的坐标为 a k a_k ak,则由题意计算出的距离应该为:
d i s t = ∑ i = 0 k ( x − a i ) + ∑ i = k + 1 n − 1 ( a i − x ) = ( k + 1 ) x − ∑ i = 0 k a i + ∑ i = k + 1 n − 1 a i − ( n − 1 − k ) x dist=\sum_{i=0}^k(x-a_i)+\sum_{i=k+1}^{n-1}(a_i-x)=(k+1)x-\sum_{i=0}^ka_i+\sum_{i=k+1}^{n-1}a_i-(n-1-k)x dist=i=0k(xai)+i=k+1n1(aix)=(k+1)xi=0kai+i=k+1n1ai(n1k)x
根据上面的推导最直观的思路就是枚举从 a 0 → a i a_0\to a_i a0ai 的所有坐标,然后老老实实地计算每个 d i s t dist dist 取最小值,这种思路需要用到二分,具体见代码。

这里要记录的并不是像上面那样简单模拟的思路,而是更为巧妙一些的:

假设给出的商店坐标(排好序之后)为 1 , 2 , 6 , 9 1,2,6,9 1,2,6,9
则按上面模拟的思路计算可得:

货仓位置距离
114
212
312
412
512
612
714
816
918

为什么不枚举小于 a 0 a_0 a0 和大于 a n a_n an 的位置呢?这个问题留给读者。
由上面的表格可以得出,似乎越往商店的中部位置靠近,距离就越短
不妨直接研究中部的商店,这里的商店数是偶数个,则研究中间的两个商店,我们会得到一个有趣的结论:
在中部的两个商店之间建立货仓的话,各商店到货仓的距离是不变的,并且距离为两两对称的商店之间的距离之和,比如例子里面的距离就是 6 − 2 + 9 − 1 = 12 6-2+9-1=12 62+91=12
所以这题可以直接求两两对称商店的距离之差的和即可,奇数个商店数就将货仓建立在最中间的商店处即可。具体的证明这里不做记录,但是是很容易想通的。

代码

代码一:二分模拟

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
typedef long long LL;int cmp(const void* a, const void* b) { return *(int*)a - *(int*)b; }// 寻找第一个小于等于 target 的元素的下标,没有则返回 -1
int first_le(int* arr, int n, int target) {int l = 0, r = n - 1, mid = 0;while (l <= r) {mid = l + ((r - l) >> 1);if (arr[mid] <= target) {if (mid == n - 1 || arr[mid + 1] > target) {return mid;}l = mid + 1;} else {r = mid - 1;}}return -1;
}int main(void) {int n = 0;scanf("%d", &n);int a[n], i = 0;for (i = 0; i < n; i++) {scanf("%d", a + i);}qsort(a, n, sizeof(int), cmp);LL sum[n], ans = LLONG_MAX, t = 0;sum[0] = a[0];for (i = 1; i < n; i++) {sum[i] = sum[i - 1] + a[i];}for (LL x = a[0]; x <= a[n - 1]; x++) {i = first_le(a, n, x);t = (i + 1) * x - sum[i] + sum[n - 1] - sum[i] - (n - 1 - i) * x;if (t < ans) ans = t;}printf("%lld\n", ans);return 0;
}

代码二:数学推导

#include <stdio.h>
#include <stdlib.h>#define N 1000005typedef long long LL;int cmp(const void* a, const void* b) { return *(int*)a - *(int*)b; }int main(void) {int n = 0;scanf("%d", &n);int a[n], i = 0;LL ans = 0;for (i = 0; i < n; i++) {scanf("%d", a + i);}qsort(a, n, sizeof(int), cmp);for (i = n >> 1; i < n; i++) {ans += a[i] - a[n - i - 1];}printf("%lld\n", ans);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/792290.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot整合Flowable/Activiti

SpringBoot版本: 2.0.1.RELEASE Flowable版本: 6.3.1 Activiti版本: 6.0.0 一.添加pom依赖 因为之前我整合的时候有报错关于sqlsession的错误,后面查询文章才发现flowable要排除掉mybatis,又没说具体排除哪一个,所以我这干脆全部排除了 <!-- Flowable dependencies -->…

练气第六天

问:ANR怎么分析&#xff1f; ANR问题&#xff0c;这其实是一个非常综合性的问题&#xff0c;因为anr会涉及CPU负载&#xff0c;内存空间大小&#xff0c;线程锁&#xff0c;GC回收&#xff0c;这里面每个点&#xff0c;都是非常考验我们基本功的。 分析ANR问题&#xff0c;需…

【Java SE】继承

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. 继承1.1 继承是什么1.2 继承的意义1.3 继承的语法1.4 继承的方式1.5 子类中访问父类成员1.5.1 子类中访问…

js类型转换

类型转换只有这四种&#xff0c;例如如果要对象转数字&#xff0c;那么就需要先把对象转成原始类型&#xff0c;再从原始类型转到数字。 空数组转原始类型是一个空字符串。空对象转原始类型是[object Object]。 let a {} console.log(a);// NaN //等价于 a->原始 然后原始…

北京大学创新推出ManipLLM黑科技 | 大幅提升机器人操作的鲁棒性与智能性

机器人操作依赖于准确预测接触点和执行器方向以确保成功操作。然而&#xff0c;基于学习的机器人操作&#xff0c;在模拟器中仅针对有限类别进行训练&#xff0c;往往难以实现泛化&#xff0c;特别是在面临大量类别时。 因此&#xff0c;作者提出了一种创新的方法&#xff0c;…

使用c++ lambda表达式的注意事项

回答来自【通义灵码】 使用C中的lambda表达式时&#xff0c;应当注意以下几点&#xff1a; 语法结构: 捕获列表 ([captures])&#xff1a;位于lambda表达式起始处&#xff0c;定义了lambda可以访问的外部作用域中的变量。可选择捕获方式包括&#xff1a; 按值捕获 ([])&#x…

网络安全基础之网络协议与安全威胁

OSI(OpenSystem Interconnect)&#xff0c;即开放式系统互联。 一般都叫OSI参考模型&#xff0c;是ISO(国际标准化组织)组织在1985年研究的网络互联模型。 网络协议的简介&#xff1a; 定义&#xff1a;协议是网络中计算机或设备之间进行通信的一系列规则集合。 什么是规则?…

Android操作sqlite数据库

Sqlite数一种轻量级的关系型数据库&#xff0c;android里面可以用来持久化存储一些用户数据。 一、SQLiteOpenHelper方式 SQLiteOpenHelper是原生的数据库帮助类&#xff0c;继承这个类&#xff0c;用来创建&#xff0c;更新数据库的操作 public class MySqliteOpenHelper e…

算法整理:链表

链表定义 struct ListNode { int val;ListNode *next;ListNode(int x) : val(x), next(nullptr) {} }; 链表的遍历&#xff1a;ListNode phead; while(p!null) pp.next; 找到链表的尾结点&#xff1a;phead; while(p.next!null)pp.next; 链表节点的个数&#xff1a; phead…

LocalDateTime 前后端传输问题

后端使用json形式接收前端传来的LocalDateTime&#xff0c;则添加下面的JsonFormat注释 同时后端返回给前端的json中带有LocalDateTime的话&#xff0c;也添加JsonFormat注解 JsonFormat(pattern "yyyy-MM-dd HH:mm:ss", timezone "GMT8") private Loca…

蓝桥杯真题:七段码

import java.util.Scanner; import java.util.ArrayList; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args){// 连接关系图int[][] map new int[][]{{0, 1, 0, 0, 0, 1, 0},{1, 0, 1, 0, 0, 0, 1},{0, 1, 0, 1, 0, 0…

通讯录项目实现

引言&#xff1a;通过顺序表的逻辑实现通讯录。这里就不讲关于顺序表的函数了。如果有不明白的可以看我写的顺序表的博客。 目录 顺序表与通讯录的比较 各源文件文件大榄 Contact.c中通讯录相关函数的定义 初始化和销毁通讯录 添加联系人&#xff1a; 删除联系人&#xf…

c++的学习之路:10、string(2)

本章主要说一下模拟实现string类的部分功能&#xff0c;文章末附上所有代码。 目录 一、构造函数与析构函数 二、拷贝构造 三、c_str 四、【】和迭代器的遍历与访问 五、size 六、判断 七、reserve 八、push_back 九、resize 十、append 十一、 十二、insert 十…

Spirngboot JWT快速配置和使用

2、JWT 2.1、JWT介绍 JWT是JSON Web Token的缩写&#xff0c;即JSON Web令牌&#xff0c;是一种自包含令牌。 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。 JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息&#xff0c;以便于从…

day25打卡:回溯算法part02

day25打卡&#xff1a;回溯算法part02 216.组合总和三 原题链接 代码随想录链接 和经典的回溯题目很相似&#xff0c;只是需要在每层for循环中都记录当前的总和&#xff1b; Java代码如下&#xff1a; class Solution {List<List<Integer>> result new Arra…

【DevOps工具篇】Keycloak中设置与OpenLDAP认证集成

【DevOps工具篇】Keycloak中设置与OpenLDAP认证集成 目录 【DevOps工具篇】Keycloak中设置与OpenLDAP认证集成步骤 1. 启动一个用于安装 OpenLDAP 的 EC2 实例步骤 2. 安装 OpenLDAP启动 docker 容器查看所有用户信息extended LDIFLDAPv3base <ou=users,dc=example,dc=org&g…

Redis的5大常见数据类型的用法

上一篇文章我们讲了Redis的10大应用场景&#xff0c;这一篇文章就针对Redis的常用数据结构进行一个说明&#xff0c;通过示例的形式演示每一种数据结构如何使用。 当涉及Redis的数据操作时&#xff0c;不同数据类型对应的不同数据结构&#xff0c;如下就对5大常用的数据类型进行…

Transformer,革命性的深度学习架构

Transformer 是一种革命性的深度学习架构&#xff0c;专门设计用于处理序列数据&#xff0c;特别是在自然语言处理&#xff08;NLP&#xff09;任务中表现卓越。它由 Vaswani 等人在 2017 年发表的论文《Attention is All You Need》中首次提出&#xff0c;打破了当时基于循环神…

2024最新版Android studio安装入门教程(非常详细)

目录 JDK安装与配置 一、下载JDK 二、JDK安装 三、JDK的环境配置 四、JDK的配置验证 Android studio安装 Android studio连接手机真机调试&#xff08;以华为鸿蒙为例&#xff09; 一、新建一个android项目 二、进入项目面板 三、配置Android Studio 四、安装手机驱…

【linux】进程替换的应用|shell解释器的实现

当我们学过了进程替换之后&#xff0c;本篇文章可以根据进程替换的知识带你自主实现一个shell命令行 实现步骤 1.显示命令行提示 2.读取输入指令以及对应选项 3.分割第二步的指令以及选项到命令行参数表中 4.处理内建命令 5.进程替换 1.显示命令行提示 我们通过观察bash的命令行…