算法分析与设计第一次作业(分治法)

1. 首先复习一下平均时间复杂度为O(n)=n*log(n)的快速排序

//quicksort
//从小到大排序 
#include<iostream>
using namespace std;
void printf_shuzu(int name1[],int s){
    for(int i=0;i<s;i++){
        cout << name1[i]<<" ";
    }
    cout<<endl;
}
void swap1(int *x,int *y){
    int temp;
    temp = *x;
    *x = *y;
    *y =temp;
}
int quicksortpartion(int x[],int l,int r){
    int temp = x[l],i=l,j=r;
    while(i<j){
        //从右找到一个比 temp小的 
        while(i<j&&x[j]>temp) j--;
        if(i<j) x[i++] = x[j];
        //从左找一个 
        while(i<j&&x[i]<temp) i++;
        if(i<j) x[j--] = x[i];
         
    }
    x[i]=temp;
    return i;
}
void quicksort( int m[],int l,int r){
    if (l>=r){
        return ;
    }

    int i =quicksortpartion(m,l,r);
    quicksort(m,l,i-1);
    quicksort(m,i+1,r);
}

int main(){
    int m[] = {1,2,5,6,8,2,45,6};
    int len = sizeof(m)/sizeof(m[0]);
    printf_shuzu(m,8);
    quicksort(m,0,7);
    printf_shuzu(m,8);
    return 0;
} 

 里面有一个编程小技巧是记录一个temp以后可以始终通过双向查找,获得移动的空间

2.  复习一下时间复杂度为O(n)=n*log(n)的归并排序,参考归并排序

//Merge_Sort归并排序
#include<iostream>
using namespace std;
void printf_shuzu(int name1[],int s){
    for(int i=0;i<s;i++){
        cout << name1[i]<<" ";
    }
    cout<<endl;
}
void Merge(int x[],int l1,int r1,int l2,int r2){
    int y[100];int i=l1,k=l1;
    while(l1<=r1&&l2<=r2){
        if(x[l1]<x[l2]){
            y[k++]=x[l1++];
        }else{
            y[k++]= x[l2++];
        }
    }
    while(l1<=r1){
        y[k++]=x[l1++];
    }
    while(l2<=r2){
        y[k++]=x[l2++];
    }
    
    while    (i<=r2){
        x[i]=y[i++];
    }
}
void Merge_sort1(int x[],int l,int r){
    //先确定递归边界 
    if(l<r){
        int t=(l+r)/2;
        Merge_sort1(x,l,t);
        Merge_sort1(x,t+1,r);
        Merge(x,l,t,t+1,r);
    }
    
}

int main(){
    int m[] = {1,2,5,6,8,2,45,6};
    int len = sizeof(m)/sizeof(m[0]);
    printf_shuzu(m,8);
    Merge_sort1(m,0,len-1   );
    printf_shuzu(m,8);
    return 0;
} 

 3.课程作业,寻找无序的多个区间的最大重合段,根据老师课上的提示,有两种思路,

(1). 按照区间的左端点排序,线性计算重合区间,遍历到最后就可以得到最大值;

其思路的关键在于将无序的区间集合按照左端点排序之后,重合区间只有三种可能,

a. x2>y1 重合区间不存在

b. x2<y1 &&y2<=y1 重合区间为y2-x2

c. x2<y1 &&y2>y1  重合区间为y1-x2

需要注意的是,这里需要声明一个变量right 来记录扫描过程中的最左侧端点 

//zuidaconghequjian
#include<iostream>
#include<algorithm>
using namespace std;
struct qujian{
int x,y;
}qujian1[100];


bool cmp(qujian a,qujian b)
{
return a.x<b.x;
}
int main(){
int t;
cin>>t;
for(int i=0;i<t;i++){
cin>>qujian1[i].x>>qujian1[i].y;
}
sort(qujian1,qujian1+t,cmp);

int ans=-1,temp,righht = qujian1[0].y ;
for(int i=0;i<t-1;i++){
if(qujian1[i+1].x < qujian1[i].y){
if(qujian1[i+1].y>righht){
//更新右边界
temp=righht-qujian1[i+1].x;
righht = qujian1[i+1].y;
}else{
temp = qujian1[i+1].y-qujian1[i+1].x;
}


}
if(ans<temp) ans = temp;
}
cout<<"最大区间为"<<ans<<endl;
return 0;
}

 

(2).按照分治法的思路:

 

codeForces刷题第一次作业部分

posted @ 2020-09-23 21:57  兀凯奇  阅读(205)  评论(0)    收藏  举报