当前位置: 首页 > article >正文

【算法】火柴排队(离散化、归并排序)

涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:

∑i=(ai−bi)^2,其中 ai 表示第一列火柴中第 i个火柴的高度,bi表示第二列火柴中第 i个火柴的高度。 

每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。

请问得到这个最小的距离,最少需要交换多少次?

如果这个数字太大,请输出这个最小交换次数对 99,999,997取模的结果。

输入格式

共三行,第一行包含一个整数 n,表示每盒中火柴的数目。 

第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。

第三行有 n个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。

输出格式

输出共一行,包含一个整数,表示最少交换次数对 99,999,997取模的结果。

数据范围

1≤n≤1e5
0≤火柴高度≤2e31-1

输入样例:
4
2 3 1 4
3 2 1 4
输出样例:
1

 离散化模板:

把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小

如这一道题就将2e9转化为2e5,节约空间

void work(int a[]){
    for(int i=1;i<=n;i++){
        p[i]=i;//存放离散化的下标
    }
    sort(p+1,p+n+1,[&](int x,int y){return a[x]<a[y];});//升序
    for(int i=1;i<=n;i++){
        a[p[i]]=i;
    }
}

归并排序模板:

 int merge_sort(int l,int r){//归并排序可以求出逆序对的数量
    if(l>=r) return 0;
    int mid=(l+r)>>1;
    int res=merge_sort(l,mid)+merge_sort(mid+1,r);
    int i=l,j=mid+1,k=0;
    while(i<=mid&&j<=r){
        if(b[i]<b[j]) p[k++]=b[i++];
        else{
            p[k++]=b[j++];
            res=res+mid-i+1;
        } 
    }
    while(i<=mid) p[k++]=b[i++];
    while(j<=r) p[k++]=b[j++];
    for(i=l,j=0;j<k;i++,j++){
        b[i]=p[j];
    }
    return res;
}

映射:

 

#include<iostream>
#include<algorithm>
#define N 100010
#define MOD 99999997
using namespace std;

int n;
int a[N],b[N],c[N],p[N];

void work(int a[]){
    for(int i=1;i<=n;i++){
        p[i]=i;//存放离散化的下标
    }
    sort(p+1,p+n+1,[&](int x,int y){return a[x]<a[y];});//升序
    for(int i=1;i<=n;i++){
        a[p[i]]=i;
    }
}

int merge_sort(int l,int r){//归并排序可以求出逆序对的数量
    if(l>=r) return 0;
    int mid=(l+r)>>1;
    int res=(merge_sort(l,mid)+merge_sort(mid+1,r))%MOD;
    int i=l,j=mid+1,k=0;
    while(i<=mid&&j<=r){
        if(b[i]<b[j]) p[k++]=b[i++];
        else{
            p[k++]=b[j++];
            res=(res+mid-i+1)%MOD;
        } 
    }
    while(i<=mid) p[k++]=b[i++];
    while(j<=r) p[k++]=b[j++];
    for(i=l,j=0;j<k;i++,j++){
        b[i]=p[j];
    }
    return res;
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=n;i++){
        cin>>b[i];
    }
    
    work(a),work(b);//将a,b离散化
    for(int i=1;i<=n;i++){
        c[a[i]]=i;//将a数组中的元素赋值为其下标并存在数组c中
                  //a数组相当与升序
    }
    for(int i=1;i<=n;i++){
        b[i]=c[b[i]];//映射,b数组的值要先去查找a数组所对应的下标值
    }
    cout<<merge_sort(1,n);//归并排序
    return 0;
    
}


http://www.kler.cn/a/271980.html

相关文章:

  • 【C++图论 并集查找】2492. 两个城市间路径的最小分数|1679
  • 网络安全 | 入侵检测系统(IDS)与入侵防御系统(IPS):如何识别并阻止威胁
  • npm install 报错:Command failed: git checkout 2.2.0-c
  • 【mptcp】ubuntu18.04和MT7981搭建mptcp测试环境操作说明
  • 一文大白话讲清楚webpack基本使用——11——chunkIds和runtimeChunk
  • nuxt3项目打包部署到服务器后配置端口号和开启https
  • 如何使用vue定义组件之——父组件调用子组件数据
  • 【2024第一期CANN训练营】4、AscendCL推理应用开发
  • QT----基于QT的人脸考勤系统
  • ROS 语音交互(二)nlp
  • 贡献法:USACO 2021 December Contest Bronze:孤独的照片
  • reloading,一个很实用的Python库!
  • 2024年视频制作软件哪个好用?盘点10个视频剪辑软件,哪个更适合你
  • Flink程序员开发利器本地化WebUI生成
  • 机器人路径规划:基于改进型A*算法的机器人路径规划(提供Python代码)
  • 【Jetson Nano】jetson nano一些基本功能命令
  • 某赛通电子文档安全管理系统 DecryptApplication 任意文件读取漏洞(2024年3月发布)
  • PHP魔术方法详解
  • 【软考高项】七、信息技术发展之存储、数据库、信息安全
  • Vue-router3.0版本跳转报错
  • 【MySQL】ROW_NUMBER 窗口函数妙用之报告系统状态的连续日期
  • Springboot 整合 Elasticsearch(五):使用RestHighLevelClient操作ES ②
  • ClickHouse中的设置的分类
  • 【LeetCode热题100】24. 两两交换链表中的节点(链表)
  • 树与二叉树(数据结构)
  • 前端学习之css伪元素选择器