• 超车(求逆序对个数)


      jzabc除了对多米诺骨牌感兴趣外,对赛车也很感兴趣。上个周末他观看了一场赛车比赛。他总是能想出许多稀奇的问题。某一时刻,他看到有n辆车(总是匀速行驶)在同一直线上,并且处在一个无限长度的直道上,而且n辆车有严格的先后之分。他通过特殊的器材测出了每一辆车的速度。那么问题出现了,如果有两辆车A车和B车,A车在B车的后面,并且A车的速度比B车的快,那么经过一段时间后,A车一定会超过B车。我们称之为一次超车。那么他想请你帮忙计算超车总数。我们记车道起点的坐标为0。没有两辆车的坐标相同。

    输入格式:

    第一行,一个数n,车辆总数。
    第二行至第n+1行,为n辆车的信息
    每行有两个正整数x,y,x和y之间有一个空格
    x为车的坐标,y为车的速度
    0<x,y<=1000000000,

    输出格式:

    一行,超车总数。

    样例输入:

    2
    5 6
    2 8

    样例输出:
    1

    题解:

    这道题其实就是求逆序对的个数

    因为没有两辆车的坐标相同,所以可以先对坐标排序,然后求速度的逆序对个数,就是超车数

    =============分割线==============

    方法有两个,一个是利用归并排序,排序的次数就是逆序对的个数

    还有一个貌似是使用树状数组,有时间再试试吧...

    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int n;
    long long temp[310000],ans=0;//temp用作存储临时的数据
    
    struct str
    {
        long long coo,spe;
    }a[310000];
    
    bool cmp(str a,str b)
    {
        return a.coo<b.coo;
    }
    
    void merge_array(int x,int y)//合并两个数组
    {
        int i=x;
        int mid=(x+y)/2;
        int j=mid+1;
        int k=x;
        
        while(i<=mid && j<=y)
        {
            if(a[i].spe>a[j].spe)
            {
                temp[k++]=a[j++].spe;
                ans+=mid-i+1;  //a[i..mid]已经有序了,那么a[i+1], a[i+2], ... a[mid]都是大于a[j]的,
            }
            else
                temp[k++]=a[i++].spe;
        }
        
        while(i<=mid)
            temp[k++]=a[i++].spe;
        
        while(j<=y)
            temp[k++]=a[j++].spe;
        
        for(int i=x;i<=y;i++)  
            a[i].spe=temp[i];  
    }
    
    void merge_sort(int x,int y)
    {
        if(x<y)
        {
            int mid=(x+y)/2;
            merge_sort(x,mid);
            merge_sort(mid+1,y);
            merge_array(x,y);
        }
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i].coo>>a[i].spe;
        sort(a+1,a+1+n,cmp);
        merge_sort(1,n);
        cout<<ans<<endl;
        
        return 0;
    }
  • 相关阅读:
    ReentrantReadWriteLock源码探究
    ReentrantLock源码探究
    CyclicBarrier源码探究 (JDK 1.8)
    ThreadLocal源码探究 (JDK 1.8)
    CountDownLatch源码探究 (JDK 1.8)
    ConcurrentHashMap源码探究 (JDK 1.8)
    备忘录模式
    variable precision SWAR算法
    建造者模式
    Spring MVC 解决乱码
  • 原文地址:https://www.cnblogs.com/kekit/p/6483224.html
Copyright © 2020-2023  润新知