第一次实验课总结

算法分析与设计第一次实验课总结

第一题

7-1 maximum number in a unimodal array (40 )

You are a given a unimodal array of n distinct elements, meaning that its entries are in increasing order up until its maximum element, after which its elements are in decreasing order. Give an algorithm to compute the maximum element that runs in O(log n) time.

输入格式:

An integer n in the first line, 1<= n <= 10000. N integers in the seconde line seperated by a space, which is a unimodal array.

输出格式:

A integer which is the maximum integer in the array

输入样例:

7

1 2 3 9 8 6 5

结尾无空行

输出样例:

9

结尾无空行

题目描述:本题为求解一个先递增后递减的数组的最大元素

解决方法:通过递归调用二分法,不断将数组对半分,将中间的数与它相邻的两数比较,有三种情况:

(1)    若中间元素同时大于它两边的数,则该数即为最大的数,返回该数

(2)    若中间元素小于它左边的数大于右边的数,则将right下标改为mid-1

(3)    若中间元素大于它左边的数小于右边的数,则将left下标改为mid+1

题解:

#include <iostream>

#define N 10000

using namespace std;

 

int a[N];

 

int Search(int a[],int left,int right){

        while(left<=right){

                 int mid=(left+right)/2;

        if(a[mid]>a[mid+1]&&a[mid]>a[mid-1]){

            return mid;

        }else if(a[mid]<a[mid-1]&&a[mid]>a[mid+1]){

                 right=mid-1;

        }else{

                 left=mid+1;

        }

        }

}

 

int main(int argc, char** argv) {

        int n;

        cin>>n;

    int left=0,right=n-1;

        for(int i=0;i<n;i++){

                 cin>>a[i];

        }

        int k=Search(a,left,right);

        cout<<a[k];

        return 0;

}

 

第二题

7-2 二分法求函数的零点 (30 )

  • 有函数:f(x)=x5−15x4+85x3−225x2+274x−121 已知f(1.5)>0,f(2.4)<0 且方程f(x)=0 在区间[1.5,2.4] 有且只有一个根,请用二分法求出该根。 提示:判断函数是否为0,使用表达式 fabs(f(x)) < 1e-7

输入格式:

无。

输出格式:x

该方程在区间[1.5,2.4]中的根。要求四舍五入到小数点后6位。。

输入样例:

结尾无空行

输出样例:

结尾无空行

题目描述:

本题求解函数f(x)=x5−15x4+85x3−225x2+274x−121在区间[1.5,2.4]的零点

解决方法:根据逼近的思路,通过不断调用二分法来缩短区间,每二分一次,将区间的中间值对应的函数值与1e-7比较,有三种情况:

(1)     f(mid)<1e-7,修改right=mid-1后调用二分法

(2)     f(mid)>1e-7,修改left=mid+1后调用二分法

(3)     f(mid)=1e-7,返回mid

 题解:

#include <iostream>

#include <cmath>

using namespace std;

 

double fx(double x){

       return  pow(x,5)-15*pow(x,4)+85*pow(x,3)-225*pow(x,2)+274*x-121;

}

 

double BSearch(double left,double right){

       double mid = (left+right)/2.0;

       double result = fx(mid);

       if(result>1e-7){

              return BSearch(mid+1,right);

       }else if(result<-1e-7){

              return BSearch(left,mid-1);

       }else{

        return mid;

    }

      

}

 

 

int main(int argc, char** argv) {

       double k =BSearch(1.5,2.4);

       printf("%.6lf",k);

       return 0;

}

第三题

7-3 两个有序序列的中位数 (30 )

已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0​,A1​,⋯,AN−1​的中位数指A(N−1)/2​的值,即第⌊(N+1)/2⌋个数(A0​为第1个数)。

输入格式:

输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。

输出格式:

在一行中输出两个输入序列的并集序列的中位数。

输入样例1:

5
1 3 5 7 9
2 3 4 5 6
结尾无空行

输出样例1:

4
结尾无空行

输入样例2:

6
-100 -10 1 1 1 1
-50 0 2 3 4 5

输出样例2:

1

题目描述:本题求解两个数组所有元素合并后的中位数,要求使劲按复杂度为log n;

解决方法:通过递归调用二分法不断舍去两个数组中不可能为中位数的元素,分为奇偶两种情况,共三种情况:

(1)     数组1的中间数等于数组2的中间数,则返回数组1或2中的任意一个数

(2)     数组1的中间数小于数组2的中间数, right1=mid1(奇数要加1),left=mid2

(3)     数组1的中间数大于数组2的中间数leftt1=mid1,right=mid2(奇数要加1)

题解:

#include <iostream>

#define N 100000

using namespace std;

 

int  a[N],b[N];

 

int BSearch(int a[],int l1,int r1,int b[],int l2,int r2){

       if(l1>=r1||l2>=r2){

           return a[l1]>b[l2]?b[l2]:a[l1];

       }

       int mid1 = (l1+r1)/2;

       int mid2 = (l2+r2)/2;

    if(a[mid1]==b[mid2]){

    return a[mid1];

       } else if(a[mid1]<b[mid2]){

              if((l1+r1)%2==0)  return BSearch(a,mid1,r1,b,l2,mid2);

              else return BSearch(a,mid1+1,r1,b,l2,mid2);

       }else{

              if((l2+r2)%2==0)  return BSearch(a,l1,mid1,b,mid2,r2);

              else return BSearch(a,l1,mid1,b,mid2+1,r2);

       }

}

 

 

int main(int argc, char** argv) {

       int n;

       cin>>n;

       for(int i=0;i<n;i++){

              cin>>a[i];

       }

       for(int i=0;i<n;i++){

              cin>>b[i];

       }

       cout<<BSearch(a,0,n-1,b,0,n-1);

       return 0;

}

 

posted @ 2021-10-13 23:30  暖云  阅读(32)  评论(0编辑  收藏  举报