分析
将所有的数据放到一个大的数组中进行排序,只不过这个大数组中有三类数,分别是S1,S2,S3中的数,所以可以用一个id来对每个集合S中的数进行特殊标记。
之后开始在排序好的数组中对临近的3个来自不同集合中的数的差的绝对值之和的最小值进行查找,结果存放在ans中。
拿样例来说
我们排序后的大数组中相邻的3个来自不同集合中的数,他们的差的绝对值之和一定是最小的。本样例中9 9 10是最佳答案,来自3个集合,差的绝对值之和最小。
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 3e5+10,INF = 0x3f3f3f3f;
int l,m,n;
struct node{
int id,val; //id对每个集合S的数进行标记,val是每个数的值
bool operator<(const node& p) const{ //从小到大排序
if(val!=p.val) return val<p.val;
return id<p.id;
}
}a[N];
LL ans=4e9;
int main()
{
scanf("%d%d%d",&l,&m,&n);
for(int i=0;i<l;i++) //输入S1的所有数
{
scanf("%d",&a[i].val);
a[i].id=1;
}
for(int i=l;i<l+m;i++) //输入S2的所有数
{
scanf("%d",&a[i].val);
a[i].id=2;
}
for(int i=l+m;i<l+m+n;i++) //输入S3的所有数
{
scanf("%d",&a[i].val);
a[i].id=3;
}
sort(a,a+l+m+n); //将大数组进行排序
int s1=INF,s2=INF,s3=INF; //首先将邻近的三个集合中的数的初始值赋为INF
for(int i=0;i<l+m+n;i++)
{
if(a[i].id==1) s1=a[i].val;
if(a[i].id==2) s2=a[i].val;
if(a[i].id==3) s3=a[i].val;
if(s1!=INF && s2!=INF && s3!=INF) //当找到3个临近的数时,就将差的绝对值之和与ans进行比较
{
ans=min(ans,(LL)abs(s1-s2)+(LL)abs(s1-s3)+(LL)abs(s2-s3));
}
}
printf("%lld",ans);
return 0;
}
可以的~
思路很好懂