zoukankan      html  css  js  c++  java
  • 【NOIP2013】火柴排队

    如果没有这道题的话我连逆序对是啥都不知道QAQ

    原题:

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

    ,其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二列火柴中第 i 个火柴的高度。
    每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。

    1 ≤ n ≤ 100,000,0 ≤火柴高度≤ 2^31-1。

    首先根据距离定义式可以看粗来,让距离最小,就是让第一列中的第k小的火柴和第二列中的第k小的火柴对齐,而且只能相邻的两个交换,这就是个冒泡

    冒泡排序中,如果要把序列排成升序,呢么如果存在i<j && a[i]>a[j],呢么a[i]和a[j]一定要交换,因为a[i]要往右走,a[j]要往左走

    定义id为a排序前的位置,数组c为a[i].id对应的b[i].id,呢么就是求c中的逆序对个数,即让两列中第k小的火柴对齐需要的最小交换次数

    归并求逆序对即可

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 int read(){int z=0,mark=1;  char ch=getchar();
     8     while(ch<'0'||ch>'9'){if(ch=='-')mark=-1;  ch=getchar();}
     9     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    10     return z*mark;
    11 }
    12 int mo=99999997;
    13 int n;
    14 struct cdd{int num,id;}a[110000],b[110000];
    15 int c[110000];
    16 int d[110000],dtou=0;
    17 int bowl=0;
    18 bool compare(cdd x,cdd y){return x.num<y.num;}
    19 void bing(int _left,int _right){
    20     int mid=(_left+_right)/2;  dtou=_left-1;
    21     int i=_left,j=mid+1;
    22     while(i<=mid && j<=_right){
    23         if(c[j]<c[i]){  d[++dtou]=c[j++];  bowl=(bowl+mid-i+1)%mo;}
    24         else  d[++dtou]=c[i++];
    25     }
    26     while(i<=mid)  d[++dtou]=c[i++];//序列是单调的,所以后面的肯定也都大于前面的
    27     while(j<=_right)  d[++dtou]=c[j++];
    28     for(int i=_left;i<=_right;i++)
    29         c[i]=d[i];
    30 }
    31 void gui(int _left,int _right){
    32     if(_left<_right){
    33         int mid=(_left+_right)/2;
    34         gui(_left,mid),gui(mid+1,_right);
    35         bing(_left,_right);
    36     }
    37 }
    38 int main(){//freopen("ddd.in","r",stdin);
    39     cin>>n;
    40     for(int i=1;i<=n;i++)  a[i].num=read(),a[i].id=i;
    41     for(int i=1;i<=n;i++)  b[i].num=read(),b[i].id=i;
    42     sort(a+1,a+n+1,compare),sort(b+1,b+n+1,compare);
    43     for(int i=1;i<=n;i++)  c[a[i].id]=b[i].id;
    44     gui(1,n);
    45     /*for(int i=1;i<=n;i++)  cout<<c[i]<<" ";
    46     cout<<endl;*/
    47     cout<<bowl<<endl;
    48     return 0;
    49 }
    View Code
  • 相关阅读:
    js获取input file完整路径的方法
    form提交表单上传图片
    基于HTML5的可预览多图片Ajax上传
    ie11兼容
    上传时获取文件的完整路径图片预览的js代码(兼容Firfox和IE)
    学习笔记
    ie浏览器兼容性(ie9,ie10)
    大学最后悔的事
    easyui 分页
    jQuery学习
  • 原文地址:https://www.cnblogs.com/JSL2018/p/5893680.html
Copyright © 2011-2022 走看看