【备战秋招】每日一题:2023.03.21-阿里OD机试(第一题)-数组重排

为了更好的阅读体检,可以查看我的算法学习博客
在线评测链接: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=1naibi 尽可能小,这样才能使得他们的房子更能符合两个人的心意,请你输出一个最优解。

输入描述

第一行输入一个正整数 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,bi109

输出描述

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 | aibi求和最小.(可以使用交换法证明)所以只需将两个数组都排序,此时两个数组位置相同的元素就是最终对应位置的元素。

由于题目要求 b b b数组不能移动,所以需要移动a的位置与 b b b对应,此时可以记录一个b数组每个元素对应的下标,第一次按元素大小排序,第二遍按下标大小排序,则可以达到重拍a的目的

类似题目推荐

一道非常简单的贪心题

LeetCode

LeetCode上的贪心题,代码随想录总结的非常好了,见 贪心 - 代码随想录

CodeFun2000

P1137 美团-2023.04.01-第一题-整理 --一模一样的题

P1075 拼多多-2023.3.12-飞机大战

P1176 2023.04.08-华为od-第三题-最多等和不相交连续子序列

P1211 塔子大厂真题模拟赛-第一题-魔法石(Ⅰ)

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网站注册用户名: 塔子哥学算法) 进行删除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

塔子哥学算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值