今天,学到了归并排序,最坑我的还是边界问题,不多说了,一会附代码。

考虑到逆序对问题,各种各样的边界问题,真是烦不胜烦啊。。。。。

不过归并排序还是用到了递归,今天就总结一下我认识中的递归。。。

老师们都是递归就是自己调用自己,好吧我承认,确实是,不过也太笼统了吧,这也就是一个思想,只要写好最开始的代码,后面直接递归,最开始的判读是必须的,这是题的核心判断,少了他。。。。  呵呵!

其实递归中,你不要想太多,想越多越迷,我就是这样的 ><!

哎。。。。。。。

好了,附代码吧! 这只是一道题而已,不能说明什么!。。。。  啰嗦了。。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <iomanip>
#include <ctime>
using namespace std;
long long cnt=0;  //逆序对个数;
int a[350000],c[350000];
int n;
struct node 
{
    int x,y;
}line[350000];
bool mycmp(node a,node b)
{
    return(a.x<b.x);
};
//归并排序       详情见书53页!
void worksort(int l,int  r) //r=右边界索引+1;  归并排序!
{
    int  mid,tmp,i,j;
    if(r>l+1) 
    {
        mid=(l+r)/2;  //中间边界
        worksort(l,mid-1);
        worksort(mid,r);
        tmp=l;
        for(i=l,j=mid;i<=mid-1 && j<=r;)   //l r, mid 表示下标,并不是具体的值
        {
            if(a[i]>a[j])
            {
                c[tmp++]=a[j++];
                cnt+=mid-i;  
                      //排序找逆序对个数,(mid-1)-i+1;
            }
            else
                c[tmp++]=a[i++];
        }
        if(j<=r)
            for(;j<=r;j++)
                c[tmp++]=a[j];
        else 
            for(;i<=mid-1;i++)
                c[tmp++]=a[i];
        for(i=l;i<=r;i++)
            a[i]=c[i];
    }
    else
    {
        if(l+1==r)
            if (a[l]>a[r])
            {
                swap(a[l],a[r]);
                cnt++;
            }
    }
}
int main()
{
    //freopen("1136.in","r",stdin);
    //freopen("1136.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d %d",&line[i].x,&line[i].y);
    sort(line+1,line+n+1,mycmp);
    for(int i=1;i<=n;i++)
        a[i]=line[i].y;
    worksort(1,n);  //边界不是line[1].y--line[n].y;
    cout<<cnt<<endl;
    //fclose(stdin);  fclose(stdout);
    return 0;
}
                                

 

posted on 2013-02-18 13:53  回眸只为搏笑  阅读(287)  评论(0)    收藏  举报