zoukankan      html  css  js  c++  java
  • [Luogu 1966] noip13 火柴排队

    [Luogu 1966] noip13 火柴排队

    Problem

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

    其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二列火柴中第 i 个火柴的高度。

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

    输入输出格式

    输入格式:

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

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

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

    输出格式:

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

    输入输出样例

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

    说明

    【输入输出样例说明1】

    最小距离是 0,最少需要交换 1 次,比如:交换第 1 列的前 2 根火柴或者交换第 2 列的前 2 根火柴。

    【输入输出样例说明2】

    最小距离是 10,最少需要交换 2 次,比如:交换第 1 列的中间 2 根火柴的位置,再交换第 2 列中后 2 根火柴的位置。

    【数据范围】

    对于 10%的数据, 1 ≤ n ≤ 10;

    对于 30%的数据,1 ≤ n ≤ 100;

    对于 60%的数据,1 ≤ n ≤ 1,000;

    对于 100%的数据,1 ≤ n ≤ 100,000,0 ≤火柴高度≤ maxlongint

    Solution:

    因为题目要让a[i]-b[i]的平方和最小,就是要使a[i]和b[i]越接近越好

    那么我们可以先贪心的想一想,

    如果b[1]是b数组最小的,那么与之配对的a[1]是不是也应该最小才能保证对答案的影响最小

    所以说两列火柴对应的两根火柴在各列中高度的排名应该相同,

    证明就是将"若a1>a2且b1>b2,则有(a1-b1)^2+(a2-b2)^2<(a2-b1)^2+(a1-b2)^2"这个式子展开就可以得到

    那么这样我们就可以先把b进行排序,同时找到a数组所对应的顺序,

    最后在对a数组中找逆序对就是答案

    然后求逆序对可以用归并排序或者树状数组实现

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 const int N=100010,p=99999997;
     8 struct xint{int v,num;}a[N],b[N];
     9 int n,c[N],q[N],ans;
    10 int ask(int x,int res=0){
    11     while (x){res+=c[x]; x-=x&-x;} 
    12     return res;
    13 }
    14 void add(int x){
    15     while (x<=n){c[x]++; x+=x&-x;}
    16 }
    17 bool cmp(xint x,xint y){return x.v<y.v;}
    18 int main(){
    19     scanf("%d",&n);
    20     for (int i=1;i<=n;++i) scanf("%d",&a[i].v),a[i].num=i; 
    21     for (int i=1;i<=n;++i) scanf("%d",&b[i].v),b[i].num=i;
    22     sort(a+1,a+n+1,cmp); sort(b+1,b+n+1,cmp);
    23     for (int i=1;i<=n;++i) q[a[i].num]=b[i].num;
    24     for (int i=n;i>=1;--i){
    25         (ans+=ask(q[i]-1))%=p; add(q[i]);
    26     }
    27     printf("%d",ans);
    28 }
    View Code
  • 相关阅读:
    e621. Activating a Keystroke When Any Child Component Has Focus
    e587. Filling Basic Shapes
    e591. Drawing Simple Text
    e595. Drawing an Image
    e586. Drawing Simple Shapes
    e636. Listening to All Key Events Before Delivery to Focused Component
    在 PL/SQL 块的哪部分可以对初始变量赋予新值? (选择1项)
    Oracle数据库中,在SQL语句中连接字符串的方法是哪个?(选择1项)
    你判断下面语句,有什么作用?(单选)
    Oracle数据库表空间与数据文件的关系描述正确的是( )
  • 原文地址:https://www.cnblogs.com/logic-yzf/p/7755668.html
Copyright © 2011-2022 走看看