实验一 分治与递归算法的应用

题目一:大整数乘法

  用分治算法编程实现两个n位十进制大整数的乘法运算。

#include
using namespace std;

const int Max_n=1e6+10;
char a[Max_n],b[Max_n];
int c[Max_n],d[Max_n],ans[2*Max_n];

int main(){
    while(~scanf("%s%s",a,b)){//输入 a 和 b 位数:1~1e6 
        memset(ans,0,sizeof(ans));
        int lena=strlen(a),lenb=strlen(b);
        for(int i=0;i<lena;i++) c[i]=a[lena-i-1]-'0';
        for(int i=0;i<lenb;i++) d[i]=b[lenb-i-1]-'0';
        for(int i=0;i<lena;i++)
            for(int j=0;j<lenb;j++)
                ans[i+j]+=c[i]*d[j];
        int len=lena+lenb-1;
        for(int i=0;i<len;i++){
            if(ans[i]>9){
                ans[i+1]=ans[i]/10;
                ans[i]%=10;
            }
        }
        len=a[len]?len:len-1;
        for(int i=len;i>=0;i--)
            printf("%d",ans[i]);
        printf("\n");
    }
    return 0;
}

题目二:线性时间选择

  给定n个元素和一个整数k,要求用O(n)时间找出这n个元素中第k小元素。
  思路:枢轴记录利用 ”三者取中” 的规则:比较当前表中第一个记录、最后一个记录和中间一个记录的关键字,取关键字居中的记录作为枢轴记录。找到枢轴后pivot,我们可以把小于pivot的数放在左边,否则放在右边。如果左边的数的个数 cnt (包含pivot) > k,说明第 k 小的数在这些数中,在枢轴的左边去找这个数;若cnt < k,说明这些数中没有第 k 小的数,就去枢轴的右边去找这个数,如果cnt == k,说明当前的枢轴第 k 小的数,返回即可。(这些过程类似于快排的思想即可解决)。

#include
using namespace std;

const int Max_n=1e6+10;
int a[Max_n];

int Pos(int l,int r){//三者取中
    int mid=(l+r)>>1;
    if(a[l]>a[mid]) swap(a[l],a[mid]);
    if(a[l]>a[r]) swap(a[l],a[r]);
    if(a[mid]>a[r]) swap(a[mid],a[r]);
    swap(a[l],a[mid]);
    return a[l];
}

int Quick(int k,int l,int r){
    int right=r,left=l;
    int pivot=Pos(l,r);
    while(l<r){
        while(a[r]>=pivot&&l<r) --r; a[l]=a[r];
        while(a[l]<pivot&&l<r) ++l; a[r]=a[l];
    }
    a[l]=pivot;
    if(k<l) Quick(k,left,l-1);
    else if(k>l) Quick(k,l+1,right);
    else return a[l];
}

int main(){
    int n,k;
    while(~scanf("%d%d",&n,&k)){//输出数组长度和要找到的第k小
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);//输入互不重复
        int ans=Quick(k,1,n);//第k小的数,说明这个数前面有k-1个数
        printf("%d\n",ans);
    }
    return 0;
}

题目三:二分搜索算法

  设a[0:n-1]是一个已排好序的数组。请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素的位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。并对自己的程序进行复杂性分析。

#include 
using namespace std;

typedef long long LL;
const int Max_n=(int)1e3+5;
int a[10]={1,2,3,5,6,7,8,9,10,11};

//查找是否存在x
int binarySearch1(int x){
    int left=0,right=9;
    while(left<=right){
        int mid=(left+right)/2;
        if(a[mid]==x){//找到了x
            return mid;
        }else if(a[mid]<x){//x在中点的右边
            left=mid+1;
        }else{//x在中点的左边
            right=mid-1;
        }
    }
    return -1;//最后没有找到
}

//找到>x的第一个元素
int binarySearch2(int x){
    int left=0,right=9;
    while(left<=right){
        int mid=(left+right)/2;
        if(x<a[mid]){//x在mid的左边
            right=mid-1;
        }else{//x在mid的右边
            left=mid+1;
        }
    }
    return left;
}

//时间复杂度O(logn)
int main(){
    int n;
    printf("请输入您要查找的元素:");
    while(~scanf("%d",&n)){
        int index=binarySearch1(n);
        if(index!=-1){
            printf("%d在数组中位置为:%d\n",n,index);
        }else{//说明没有此数组中没有x
            index=binarySearch2(n);
            if(index==10){
                printf("数组中没有大于%d的元素\n",n);
                printf("小于%d的最大元素位置为:%d\n",n,index);
            }else if(index==0){
                printf("大于%d的最小元素位置为:%d\n",n,index);
                printf("数组中没有小于%d的元素\n",n);
            }else{
                printf("大于%d的最小元素位置为:%d\n",n,index);
                printf("小于%d的最大元素位置为:%d\n",n,index-1);
            }
        }
        printf("请输入您要查找的元素:");
    }
    return 0;
}

你可能感兴趣的:(Algorithm)