pat b 1035 插入与归并

来源:互联网 发布:unity3d透明材质 编辑:程序博客网 时间:2024/05/19 22:23

不会,也没什么思路,脑子里只有最傻最笨的方法,但是肯定会超时。

#include <iostream>#include <algorithm>using namespace std;int cmp(int a, int b) {    return a < b;}int main() {    int n;    cin >> n;    int *a = new int [n];    int *b = new int [n];    for (int i = 0; i < n; i++) {        cin >> a[i];    }    for (int i = 0; i < n; i++) {        cin >> b[i];    }    int i, j;    for (i = 0; i < n - 1 && b[i] <= b[i + 1]; i++);    for (j = i + 1; a[j] == b[j] && j < n; j++);    if (j == n) {        cout << "Insertion Sort" << endl;        sort(a, a + i + 2, cmp);    } else {        cout << "Merge Sort" << endl;        int k = 1;        int flag = 1;        while(flag) {            flag = 0;            for (i = 0; i < n; i++) {                if (a[i] != b[i])                    flag = 1;            }            k = k * 2;            for (i = 0; i < n / k; i++)                sort(a + i * k, a + (i + 1) * k, cmp);            sort(a + n / k * k, a + n, cmp);        }    }    for (j = 0; j < n - 1; j++) {        cout << a[j] << " ";    }    cout << a[n - 1];    delete [] a;    delete [] b;    return 0;}

一开始看不懂,看了2个小时后竟然看懂了,自己在纸上模拟一边即可。


两点算法;有一个递增序列,找出和为m的两个数的位置。

    while(i<j){        if(a[i]+a[j]==m){            printf("%d %d\n",i,j);            i++;j--;        }else if(a[i]+a[j]<m){            i++;        }else if(a[i]+a[j]>m){            j--;        }    }

主函数外的数组的赋值:一开始用指针试了好久总是乱码,结果发现数组可以直接修改,因为传递的是地址。
不过学到了条经验:指针必须初始化!

void fuzhi(int a[]){    srand((unsigned)time(NULL)); /*include<cstdlib>&include<ctime>*/    for(int i=0;i<20;i++){        a[i]=rand()%500;        printf("%d ",a[i]);    }    printf("\n");    return;}int main(){    int a[20];    fuzhi(a);    for(int i=0;i<20;i++){        printf("%d ",a[i]);    }        printf("\n");    return 0;}
//指针版,dev-c和code::block都能通过,但是一些在线编译器通不过#include <iostream>using namespace std;void fu(int*  p){    for(int i=0;i<10;i++){        *(p+i)=i;    }    return ;}int main(){    int *p;    fu(p);    for(int i=0;i<10;i++){    cout << *(p+i)<<" ";    }   return 0;}

与此相同的问题还有合并两个单调数组,我在做这个练习的时候,因为”笔误“的错误耽误了很多时间。程序思路没错,但结果不对,尝试着重写程序,可能能更快的发现错误。


Dev-c 删除整行—ctrl+d
Dev-c 复制整行—ctrl+e
Dev-c可以同时编译运行多个文件,不用再打开一个IDE窗口,新建个文件就行


归并排序
递归 recursive;迭代 iteration;
1.递归实现:
这个算法我一遍写不熟,那就一遍遍的练,直到记熟为止。

void merge(int a[],int ll,int lr,int rl,int rr){    int temp[100]={};//两点:合并两个递增序列     int i=ll,j=rl,len=0;    while(i<=lr&&j<=rr){        if(a[i]<=a[j]){            temp[len++]=a[i];            i++;        }else {            temp[len++]=a[j];            j++;        }    }    while(i<=lr)temp[len++]=a[i++];    while(j<=lr)temp[len++]=a[j++];    for(int i=0;i<len;i++){        a[ll+i]=temp[i];    }}void recursiveMergeSort(int a[],int left,int right ){    if(left<right){//这是中止条件,当left>=right的时候,子函数结束,返回上一层。 //**没写会有这种情况:例{1,2,3},mid=2,会执行recursivemerge(a,3,3),mid=left=right会死循环。     int mid=(left+right)/2;    recursiveMergeSort(a,left,mid);//**第一次错写成(a,0,right),递归的每一次调用自身都一定是变量作为参数。     recursiveMergeSort(a,mid+1,right);    merge(a,left,mid,mid+1,right);          }}

2.非递归实现:
1)sort版:

void iterationMergeSort(int a[20]){    int n=20;/**注意这个k/2<=n的思路,如果是k<=n的话,还要再排序一次。k/2<=n比k<=n多执行一次,正好解决最后一趟排序。*/    for(int k=2;k/2<=n;k*=2){        for(int i=0;i<n;i=i+k) if(i+k<n)sort(a+i,a+i+k,cmp);        sort(a+n/k*k,a+n,cmp);      }}

2)非sort版
用merge()完成合并。
以后再说,目前刷题是熟练常规问题的解决

原创粉丝点击