可以发现当两个数组中的第k大与第k大分别对应时,∣ai−bi∣求和最小.(可以使用交换法证明)所以只需将两个数组都排序,此时两个数组位置相同的元素就是最终对应位置的元素。
关键在于需要重排a,b数组不能移动,所以需要移动a的位置与b对应,此时可以记录一个b数组每个元素对应的下标,第一次按元素大小排序,第二遍按下标大小排序,则可以达到重拍a的目的
C++代码
#include <bits/stdc++.h>
using namespace std;
vector<int>a;
vector<vector<int> >b;
int n;
bool cmp1(vector<int>x,vector<int>y)
{
return x[0]<y[0];
}
bool cmp2(vector<int>x,vector<int>y)
{
return x[1]<y[1];
}
int main()
{
cin>>n;
int x;
for (int i=0;i<n;i++)
{
cin>>x;
a.push_back(x);
}
for (int i=0;i<n;i++)
{
cin>>x;
vector<int>tmp{x,i};//记录元素和下标
b.push_back(tmp);
}
sort(a.begin(),a.end());
sort(b.begin(),b.end(),cmp1);//按元素大小排序
for (int i=0;i<n;i++)
b[i][0]=a[i];
sort(b.begin(),b.end(),cmp2);//按下标大小排序
for (int i=0;i<n;i++)
cout<<b[i][0]<<" ";
return 0;
}
Python代码
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
res = []
for i in range(n):
res.append([b[i], i])#记录元素和下标
res.sort(key=lambda x: x[0])#按元素大小排序
a.sort()
for i in range(n):
res[i][0] = a[i]
res.sort(key=lambda x: x[1])#按下标大小排序
for x in res:
print(x[0], end="")
有两个好朋友Alice和Bob,他们最近刚刚买了一套新房子。为了装修这个房子,他们购买了很多家具和家居用品。然而,他们的品味不太一样,Alice更喜欢现代感强一些的装饰,而Bob则更喜欢传统的装饰风格。于是,他们决定将这个房子装修成一个融合了现代与传统风格的房子。
在购买家具的时候,他们有一个共同的问题,就是如何选择合适的物品来满足他们的需求。Alice会给每个家具打一个现代风格得分,而Bob会给每个家具打一个传统风格得分。然后,他们需要从这个列表中选择一些家具,来装饰他们的新家。他们想要选择的家具应该既能满足Alice的要求,又能满足Bob的要求,因此他们需要在两个得分中都排名靠前的物品中做出选择。
在选择家具的过程中,他们发现在同一家具上,两人的得分可能会存在一些差异。于是,他们需要重新安排自己所选择的家具的顺序,来最大限度地满足双方的需求。他们想要使得他们所选择的家具的顺序,能够在两个得分中都尽可能接近排名靠前的物品。
Alice和Bob给定两个长度为n的数组a和b,现在他们需要你帮忙对a数组进行重排,使得∑i=1n∣ai−bi∣ 尽可能小,这样才能使得他们的房子更能符合两个人的心意,请你输出一个最优解。
第一行输入一个正整数n
第二行输入n个正整数ai
第三行输入n个正整数bi
1 ≤n≤ 105
1 ≤ai,bi≤109
n个正整数,代表重排后的a数组。如果有多个重排方式,输出任意即可
输入
5
1 2 3 4 5
5 4 3 2 1
输出
5 4 3 2 1