🌹作者:云小逸
📝个人主页:云小逸的主页
📝Github:云小逸的Github
🤟motto:要敢于一个人默默的面对自己,==强大自己才是核心==。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前,其次就是现在!学会自己和解,与过去和解,努力爱自己。==希望春天来之前,我们一起面朝大海,春暖花开!==🤟 👏专栏:C++👏 👏专栏:Java语言👏👏专栏:Linux学习👏
👏专栏:C语言初阶👏👏专栏:数据结构👏👏专栏:备战蓝桥杯👏
@TOC
前言
今天我们继续学习算法,加油。这篇文章写的是货仓选址问题。希望这篇可以有幸帮助到你,码字不易,请多多支持。
——————————————————————————————
题目链接:AcWing 104. 货仓选址 好的,以下是C++代码和markdown格式的题解:
AcWing 104. 货仓选址
题目描述
在一条数轴上有n个点,第i个点的位置为ai,请你求出从这些点中选出三个点,使这三个点之间的距离最小,输出这个最小距离。
输入格式
第一行输入整数n。
第二行输入n个整数,表示各个点的位置。
输出格式
输出一个实数,表示三个点之间的最小距离。结果保留两位小数。
数据范围
3≤n≤100000, 0≤ai≤1000000000
输入样例
4
6 2 9 1
输出样例
3.00
算法1
(排序+枚举)
找到三个距离最小的点,可以先将所有的点按照位置大小排序,然后枚举所有的三元组,记录最小值即可。
时间复杂度 。
C++ 代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int a[N];
int main()
{
cin >> n;
for (int i = 0; i < n; ++i) cin >> a[i];
sort(a, a + n);
double res = 1e18;
for (int i = 0; i < n; ++i)
for (int j = i + 1; j < n; ++j)
for (int k = j + 1; k < n; ++k)
{
double d = (a[k] - a[j]) * 1.0 / 2;
d = min(d, (a[j] - a[i]) * 1.0 / 2);
res = min(res, d);
}
printf("%.2lf\n", res);
return 0;
}
算法2
(排序+双指针)
时间复杂度比枚举算法更优,但是实现稍微麻烦一点。
C++ 代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int a[N];
int main()
{
cin >> n;
for (int i = 0; i < n; ++i) cin >> a[i];
sort(a, a + n);
double res = 1e18;
for (int i = 0, j = 0, k = 0; i < n; ++i)
{
while (j < i && a[i] - a[j] >= res) j++;
while (k < n && a[k] - a[i] <= res) k++;
for (int u = j; u < i; ++u)
for (int v = k; v < n && a[v] - a[u] <= res; ++v)
{
double d = (a[v] - a[u]) * 1.0 / 2;
d = min(d, (a[u] - a[i]) * 1.0 / 2);
res = min(res, d);
}
}
printf("%.2lf\n", res);
return 0;
}
算法2中,我们用两个指针j和k分别扫描前半部分和后半部分的数列,然后对于每个i位置,我们再往左走找到一个较小的j,使得j到i的距离小于当前得到的最小距离res。同理,我们也向右找一个较大的k,使得i到k的距离小于等于当前得到的最小距离res。然后在[u, v)范围内枚举所有三元组,更新最小距离。
最后
十分感谢你可以耐着性子把它读完和我可以坚持写到这里,送几句话,对你,也对我:
1.把时间尺度拉长,拉长十年看当下
2.不说负面情绪,只描述事实;
3.越专注于过好自己,能量和幸运越会照顾你;
只解决问题,不做没有意义的担心,输了就认;
4.学会原谅自己,要允许自己做错事,允许自己出现情绪波动,我知道你已经很努力很努力在做好了
5.所有你害怕的、想逃避的事情,最终都要面对,既然这样不如选择坦然面对。即使结果不如人愿,没关系,至少这个过程是享受的,而不是一路带着恐惧和害怕。
最后如果觉得我写的还不错,请不要忘记==点赞==✌,==收藏==✌,加==关注==✌哦(。・ω・。)
愿我们一起加油,奔向更美好的未来,愿我们从懵懵懂懂的一枚==菜鸟==逐渐成为==大佬==。加油,为自己点赞!