17HNUCM计科练习4题解(二分,归并排序)

目录

问题 A: 习题5-9 完数

 问题 B:  求多次落地弹球高度

 问题 C: 二分搜索(递归)

 问题 D: 二分搜索(非递归)

 问题 E: 数组合并

问题 F: 归并排序

问题 G: 线性搜索 


问题 A: 习题5-9 完数

题目描述

一个数如果恰好等于它的因子和,这个数就称为“完数”。例如,6的因子为1,2,3,而6=1+2+3,所以6是“完数”。

编程输出1000以内的所有完数,每个完数输出一行,并按下面的格式输出其因子:

6 its factors are 1,2,3

输入

输出

每个完数输出一行,并按下面的格式输出其因子:

? its factors are ?,?,?

 

样例输入 Copy

样例输出 Copy

6 its factors are 1,2,3
28 its factors are 1,2,4,7,14 
496 its factors are 1,2,4,8,16,31,62,124,248 

提示

因子包含1但不包含其本身。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int i;
	for(i=6;i<=1000;++i){
        int a[1000];
        a[0]=1;
        int s=1;
        int k=1;
        for(int j=2;j<=sqrt(i);++j){
            if(i%j==0){
                a[k]=j;
                s+=a[k];
                //cout<<a[k]<<endl;
                ++k;
                a[k]=i/j;
                s+=a[k];
                //cout<<a[k]<<endl;
                ++k;
            }
        }
            sort(a,a+k);
            if(s==i){
                cout<<s<<" its factors are ";
                for(int z=0;z<k;z++){
                    cout<<a[z];
                    if(z==k-1)
                        cout<<endl;
                    else
                        cout<<',';
                }
            }
	}
	return 0;
}

 

 问题 B:  求多次落地弹球高度

题目描述

一个球从100m的高度自由落下,每次落地后反弹回原高度的一半,再落下,再反弹。
求它从第一次落地时,到第N次落地时,共经过了多少米,第N次反弹多高。

输入

一个正整数N,表示球落地的次数。

输出

length=球第N次落地时所经过了距离
high=球第N次落地反弹的高度
小数点后保留4位小数。
注意:末尾输出换行。

样例输入 Copy

10

样例输出 Copy

length=199.8047
high=0.0977
#include<bits/stdc++.h>
using namespace std;
int main()
{
	double h,m,b,n;
    int a;
	h=100;
	m=n=h;
	cin>>a;
	b=0;
	while(a--)
	{
		m/=2;
		b+=m*2;
		n/=2;
	}
	printf("length=%.4f\nhigh=%.4f\n",b,n);
}

 

 问题 C: 二分搜索(递归)

 

题目描述

使用递归算法,实现二分搜索。

输入

多组数据输入,每组第一个数字为数组的长度n,然后输入n个整数,最后输入待查询的值。

输出

输出待查询值所在的位置,如果没有找到,则返回-1。

样例输入 Copy

3 1 2 3 2
4 0 1 3 4 2 

样例输出 Copy

2
-1
#include<bits/stdc++.h>
using namespace std;
int aa(int a[],int left,int right,int b){
    if (left<=right)
	{
		int mid = (left+right)/2;
		if(b == a[mid])
			return mid;
		else if(b<a[mid])
			return aa(a,left,mid-1,b);
		else if(b>a[mid])
			return aa(a,mid+1,right,b);
	}
	else
		return -1;
}
int main(){
	int n;
	while(cin>>n){
        int a[n],b;
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        cin>>b;
        sort(a,a+n);
        int s=aa(a,0,n,b);
        if(s>=0)
            cout<<s+1<<endl;
        else
            cout<<-1<<endl;
	}
	return 0;
}

 

 问题 D: 二分搜索(非递归)

题目描述

使用非递归算法,实现二分搜索。

输入

多组数据输入,每组第一个数字为数组的长度n,然后输入n个整数,最后输入待查询的值。

输出

输出待查询值所在的位置,如果没有找到,则返回-1。

样例输入 Copy

3 1 2 3 2
4 0 1 3 4 2 

样例输出 Copy

2
-1
#include<bits/stdc++.h>
using namespace std;
int aa(int a[],int left,int right,int b){
    while(left<=right)
	{
		int mid = (left+right)/2;
		if(b == a[mid])
			return mid;
		else if(b<a[mid])
			right=mid-1;
		else if(b>a[mid])
			left=mid+1;
	}
		return -1;
}
int main(){
	int n;
	while(cin>>n){
        int a[n],b;
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        cin>>b;
        sort(a,a+n);
        int s=aa(a,0,n,b);
        if(s>=0)
            cout<<s+1<<endl;
        else
            cout<<-1<<endl;
	}
	return 0;
}

 

 问题 E: 数组合并

 

题目描述

编写一个程序,将两个有序数组合并成一个更大的有序数组,要求时间复杂度为O(n)。

输入

多组数据输入,每组输入包括两行,每行第一个数字为数组长度n,然后输入n个有序整数。

输出

输出合并后的数组(升序),每组输出用一个空行隔开。

样例输入 Copy

3 1 3 5
3 2 4 6
2 1 2
4 3 4 5 6

样例输出 Copy

1 2 3 4 5 6

1 2 3 4 5 6
#include<bits/stdc++.h>
using namespace std;
void aa(int a[],int n,int b[],int m,int c[]){
    int i,j,p;
    i=j=p=0;
    while(i<n||j<m){
        if(i<n&&j<m){
            c[p++]=a[i]<b[j]?a[i++]:b[j++];
        }
        else if(i<n){
            c[p++]=a[i++];
        }
        else{
            c[p++]=b[j++];
        }
    }
}
int main()
{
	int n,m;
	while(cin>>n){
        int a[n];
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        cin>>m;
        int b[m];
        for(int i=0;i<m;i++){
            cin>>b[i];
        }
        int s=n+m;
        int c[s];
        aa(a,n,b,m,c);
        for(int i=0;i<s;i++){
            cout<<c[i];
            if(i==s-1)
                cout<<endl;
            else
                cout<<" ";
        }
        cout<<endl;
	}
}

 

问题 F: 归并排序

题目描述

编写一个程序,使用分治策略实现二路归并排序(升序)。

输入

多组输入,每组第一个数字为数组长度,然后输入一个一维整型数组。

输出

输出排序之后(升序)的一维整型数组,每组输出占一行。

样例输入 Copy

6 1 8 6 5 3 4
5 12 42 2 5 8

样例输出 Copy

1 3 4 5 6 8
2 5 8 12 42

 

#include<bits/stdc++.h>
using namespace std;
void Merge(int c[],int d[],int l,int m,int r){
    int i=l;
    int j=m+1;
    int k=l;
    while(i<=m&&j<=r){
        if(c[i]<c[j]){
            d[k++]=c[i++];
        }
        else{
            d[k++]=c[j++];
        }
    }
    if(i>m)
        for(int q=j;q<=r;q++){
            d[k++]=c[q];
        }
    else
        for(int q=i;q<=m;q++){
            d[k++]=c[q];
        }
}
void mergePass(int x[],int y[],int lx,int ly,int s){
    int i=0;
    while(i<=lx-2*s){
        Merge(x,y,i,i+s-1,i+2*s-1);
        i=i+2*s;
    }
    if(i+s<lx){
        Merge(x,y,i,i+s-1,lx-1);
    }
    else{
        for(int j=i;j<lx;j++){
            y[j]=x[j];
        }
    }
}
void mergeSort(int a[],int n){
    int b[n];
    int s=1;
    while(s<n){
        mergePass(a,b,n,n,s);
        s+=s;
        mergePass(b,a,n,n,s);
        s+=s;
    }
}
int main()
{
	int n;
	while(cin>>n){
        int a[n];
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        mergeSort(a,n);
        for(int i=0;i<n;i++){
            cout<<a[i];
            if(i!=n-1)
                cout<<" ";
        }
        cout<<endl;
	}
}

 

问题 G: 线性搜索 

题目描述

请编写一个程序,输入包含n(n<=10000)个整数的数列S以及包含q个(q<=500)不重复整数的数列T,输出既包含于T也包含于S的整数的个数C。S、T中的元素均大于0且小于109,T的元素不重复。

输入

第一行输入n,第二行输入代表S的n个整数,第三行输入q,第四行输入代表T的q个整数。

输出

用1行输出C。

样例输入 Copy

5
1 2 3 4 5
3
3 4 1

样例输出 Copy

3

 

#include<iostream>
#include <algorithm>
using namespace std;
int aa(int a[],int left,int right,int b){
    while(left<=right)
    {
        int mid = (left+right)/2;
        if(b == a[mid])
            return mid;
        else if(b<a[mid])
            right=mid-1;
        else if(b>a[mid])
            left=mid+1;
    }
        return -1;
}int main()
{
    int n,m;
    while(cin>>n){
        int a[n];
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        sort(a,a+n);
        cin>>m;
        int b[m];
        for(int i=0;i<m;i++){
            cin>>b[i];
        }
        int s=0;
        for(int i=0;i<m;i++){
                    //cout<<a[i]<<endl;
            if(aa(a,0,m,b[i])!=-1){
                ++s;
            }
        }
        cout<<s<<endl;
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值