为了更好的阅读体检,可以查看我的算法学习博客
在线评测链接:P1100
题目内容
有两个好朋友 A l i c e Alice Alice和 B o b Bob Bob,他们最近刚刚买了一套新房子。为了装修这个房子,他们购买了很多家具和家居用品。然而,他们的品味不太一样, A l i c e Alice Alice更喜欢现代感强一些的装饰,而 B o b Bob Bob则更喜欢传统的装饰风格。于是,他们决定将这个房子装修成一个融合了现代与传统风格的房子。
在购买家具的时候,他们有一个共同的问题,就是如何选择合适的物品来满足他们的需求。 A l i c e Alice Alice会给每个家具打一个现代风格得分,而 B o b Bob Bob会给每个家具打一个传统风格得分。然后,他们需要从这个列表中选择一些家具,来装饰他们的新家。他们想要选择的家具应该既能满足 A l i c e Alice Alice的要求,又能满足 B o b Bob Bob的要求,因此他们需要在两个得分中都排名靠前的物品中做出选择。
在选择家具的过程中,他们发现在同一家具上,两人的得分可能会存在一些差异。于是,他们需要重新安排自己所选择的家具的顺序,来最大限度地满足双方的需求。他们想要使得他们所选择的家具的顺序,能够在两个得分中都尽可能接近排名靠前的物品。
A l i c e Alice Alice和 B o b Bob Bob给定两个长度为 n n n的数组 a a a和 b b b,现在他们需要你帮忙对a数组进行重排,使得 ∑ i = 1 n ∣ a i − b i ∣ \sum_{i=1}^{n}|a_{i}-b_{i}| ∑i=1n∣ai−bi∣ 尽可能小,这样才能使得他们的房子更能符合两个人的心意,请你输出一个最优解。
输入描述
第一行输入一个正整数 n n n
第二行输入 n n n个正整数 a i a_{i} ai
第三行输入 n n n个正整数 b i b_{i} bi
1 ≤ n ≤ \leq n \leq ≤n≤ 1 0 5 10^5 105
1 ≤ a i , b i ≤ 1 0 9 \leq a_{i} ,b_{i} \leq 10^9 ≤ai,bi≤109
输出描述
n n n个正整数,代表重排后的 a a a数组。如果有多个重排方式,输出任意即可
样例
输入
5
1 2 3 4 5
5 4 3 2 1
输出
5 4 3 2 1
思路
贪心
可以发现当两个数组中的第k大与第k大分别对应时, ∣ a i − b i ∣ | a_i-b_i | ∣ai−bi∣求和最小.(可以使用交换法证明)所以只需将两个数组都排序,此时两个数组位置相同的元素就是最终对应位置的元素。
由于题目要求 b b b数组不能移动,所以需要移动a的位置与 b b b对应,此时可以记录一个b数组每个元素对应的下标,第一次按元素大小排序,第二遍按下标大小排序,则可以达到重拍a的目的
类似题目推荐
一道非常简单的贪心题
LeetCode
LeetCode上的贪心题,代码随想录总结的非常好了,见 贪心 - 代码随想录
CodeFun2000
P1137 美团-2023.04.01-第一题-整理 --一模一样的题
P1176 2023.04.08-华为od-第三题-最多等和不相交连续子序列
P1070 2023.3.7-百度-第一题-最小化k序列平均值和
代码
CPP
#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="")
Java
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();//len
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
int[][] b = new int[n][2];
for (int i = 0; i < n; i++) {
b[i][0] = sc.nextInt();
b[i][1] = i;
}
Arrays.sort(a);
Arrays.sort(b, (b1, b2) -> (b1[0] - b2[0]));
for (int i = 0; i < n; i++) {
b[i][0] = a[i];
}
Arrays.sort(b, (b1, b2) -> (b1[1] - b2[1]));
for (int i = 0; i < n; i++) {
System.out.print(b[i][0] + " ");
}
}
}
Go
package main
import (
"fmt"
"os"
"bufio"
"sort"
)
type entry struct{
val int
id int
}
func main(){
in:=bufio.NewReader(os.Stdin)
var n int
fmt.Fscan(in,&n)
a,b:=make([]int,n),make([]entry,n)
for i:=0;i<n;i++{
fmt.Fscan(in,&a[i])
}
for i:=0;i<n;i++{
fmt.Fscan(in,&b[i].val)
b[i].id=i
}
sort.Ints(a)
sort.Slice(b,func (i,j int)bool{return b[i].val<b[j].val})
ans:=make([]int,n)
for i:=0;i<n;i++{
ans[b[i].id]=a[i]
}
for i:=0;i<n;i++{
if i==0 {fmt.Printf("%d",ans[i])}else{fmt.Printf(" %d",ans[i])}
}
}
Js
let input = '';
process.stdin.resume();
process.stdin.setEncoding('utf-8');
process.stdin.on('data', (data) => {
input += data;
});
process.stdin.on('end', () => {
const lines = input.trim().split('\n');
const n = Number(lines[0]);
const a = lines[1].trim().split(' ').map(Number);
const b = lines[2].trim().split(' ').map(Number);
let res = [];
for (let i = 0; i < n; i++) {
res.push([b[i], i]);
}
res.sort((x, y) => x[0] - y[0]);
a.sort((x, y) => x - y);
for (let i = 0; i < n; i++) {
res[i][0] = a[i];
}
res.sort((x, y) => x[1] - y[1]);
let output = '';
for (let x of res) {
output += x[0];
output += " ";
}
output.slice(0 , output.length - 1);
console.log(output);
});
题目内容均收集自互联网,如如若此项内容侵犯了原著者的合法权益,可联系我: (CSDN网站注册用户名: 塔子哥学算法) 进行删除。