今天,学到了归并排序,最坑我的还是边界问题,不多说了,一会附代码。
考虑到逆序对问题,各种各样的边界问题,真是烦不胜烦啊。。。。。
不过归并排序还是用到了递归,今天就总结一下我认识中的递归。。。
老师们都是递归就是自己调用自己,好吧我承认,确实是,不过也太笼统了吧,这也就是一个思想,只要写好最开始的代码,后面直接递归,最开始的判读是必须的,这是题的核心判断,少了他。。。。 呵呵!
其实递归中,你不要想太多,想越多越迷,我就是这样的 ><!
哎。。。。。。。
好了,附代码吧! 这只是一道题而已,不能说明什么!。。。。 啰嗦了。。。。
#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; }
浙公网安备 33010602011771号