zoukankan      html  css  js  c++  java
  • NOIp2013 火柴排队

    题目描述

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

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

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

    输入输出格式

    输入格式:

    输入文件为 match.in。

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

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

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

    输出格式:

    输出文件为 match.out。

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

    输入输出样例

    输入样例#1:
    【输入输出样例 1】
    4
    2 3 1 4
    3 2 1 4
    【输入输出样例 2】
    4
    1 3 4 2
    1 7 2 4
    输出样例#1:
    【输入输出样例 1】
    1
    【输入输出样例 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

    题解:

    树状数组:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define mod 99999997 
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,ans;
    int t[100005],rank[100005];
    struct data{int v,num;}a[100005],b[100005];
    inline bool cmp1(data a,data b)
    {return a.v<b.v;}
    inline int lowbit(int x){return x&(-x);}
    inline int ask(int x)
    {
        int tmp=0;
        for(int i=x;i;i-=lowbit(i))
            tmp+=t[i];
        return tmp;
    }
    void update(int x)
    {
        for(int i=x;i<=n;i+=lowbit(i))
            t[i]++;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
            {a[i].v=read();a[i].num=i;}
        for(int i=1;i<=n;i++)
            {b[i].v=read();b[i].num=i;}
        sort(a+1,a+n+1,cmp1);
        sort(b+1,b+n+1,cmp1);
        for(int i=1;i<=n;i++)
            rank[a[i].num]=b[i].num;
        for(int i=1;i<=n;i++)
        {
            update(rank[i]);
            ans=(ans+i-ask(rank[i]))%mod;
        }
        printf("%d",ans);
        return 0;
    }

    归并排序:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define rank rk
    using namespace std;
    const int maxn=100000+5;
    const int mod=99999997;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,ans;
    int rank[maxn],tmp[maxn];
    struct node
    {
        int h,num;
        bool operator < (const node& j) const {
            return h<j.h;
        }
    }a[maxn],b[maxn];
    inline void mergesort(int l,int r)
    {
        if(l==r) return;
        int mid=l+((r-l)>>1);
        mergesort(l,mid);
        mergesort(mid+1,r);
        int x=l,y=mid+1,t=l;
        while(x<=mid&&y<=r)
        {
            if(rank[x]>rank[y])
            {
                ans+=mid-x+1;
                ans%=mod;
                tmp[t++]=rank[y++];
            }
            else
                tmp[t++]=rank[x++];
        }
        while(x<=mid) tmp[t++]=rank[x++];
        while(y<=r) tmp[t++]=rank[y++];
        for(int i=l;i<=r;i++) rank[i]=tmp[i];
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++) {a[i].h=read();a[i].num=i;}
        for(int i=1;i<=n;i++) {b[i].h=read();b[i].num=i;}
        sort(a+1,a+n+1);
        sort(b+1,b+n+1);
        for(int i=1;i<=n;i++) rank[a[i].num]=b[i].num;
        mergesort(1,n);
        printf("%d
    ",ans);
        return 0;
    }
        
        
    欢迎转载,转载请注明出处!
  • 相关阅读:
    SCAU 9504 面试
    SCAU 9503 懒人选座位
    SCAU 8628 相亲
    SCAU 10691 ACM 光环
    SCAU 8626 原子量计数
    SCAU 10674 等差对
    HDU ACM 1048 The Hardest Problem Ever (水题)
    SCAU 9502 ARDF
    SCAU 10686 DeathGod不知道的事情
    SCAU 8629 热身游戏(高精度)
  • 原文地址:https://www.cnblogs.com/huihao/p/7154270.html
Copyright © 2011-2022 走看看