17HNUCM计科练习5题解(排序)

目录

问题 A: 习题5-10 分数序列求和

问题 B: 习题5-12 猴子吃桃问题

问题 C: 快速排序 

问题 D: 随机化快速排序

问题 E: 第k大元素问题

 问题 F: 前m大数

 问题 G: Who's in the Middle


问题 A: 习题5-10 分数序列求和

题目描述

有如下分数序列

 

求出次数列的前20项之和。

请将结果的数据类型定义为double类型。

输入

输出

小数点后保留6位小数,末尾输出换行。

样例输入

样例输出

32.660261
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    int i,n;
    double s=0;
    int a,b;
    n=20;
    a=1;
    b=2;
    int k;
    for(i=0;i<n;i++){
        s+=b*1.0/a;
        k=b;
        b=a+b;
        a=k;
    }
    printf("%.6f\n",s);
    return 0;
}

 

问题 B: 习题5-12 猴子吃桃问题

题目描述

猴子第1填摘下若干桃子,当即吃了一半,还觉着不过瘾,又多吃了一个。第2天早晨,又将剩下的桃子吃掉一半,又多吃了一个。以后每天早晨都吃了前一天剩下的一半零一个。到第10天早上想再吃时,发现就只剩一个桃子了。求第1天共摘了多少个桃子。

输入

输出

一个整数,末尾换行。

样例输入

样例输出

1534

 

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,i;
    n=10;
    int b=1;
    for(i=1;i<n;++i){
        b=2*(b+1);
    }
    cout<<b<<endl;
    return 0;
}

问题 C: 快速排序 

题目描述

编程实现快速排序算法,深入理解快速排序算法的基本思想。

输入

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

输出

输出快速排序之后的一维整型数组(升序)

样例输入 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
//其实这个题直接用c++的内置函数也是可以过的,后面几个需要排序的也都是
//这里这样写是因为这算是对课内学习的检验...
#include <bits/stdc++.h>
using namespace std;
int part(int s[],int a,int b){
    int i=a;
    int j=b+1;
    int x=s[a];
    while(1){
        while(s[++i]<x&&i<b);
        while(s[--j]>x);
        if(i>=j)
            break;
        swap(s[i],s[j]);
    }
    s[a]=s[j];
    s[j]=x;
    return j;
}
void qsort(int s[],int a,int b){
    if(a<b){
        int c=part(s,a,b);
        qsort(s,a,c-1);
        qsort(s,c+1,b);
    }
}
int main()
{
    int n;
    while(cin>>n){
        int s[n];
        //memset(s,0,n*sizeof(int));
        int i;
        for(i=0;i<n;i++){
            cin>>s[i];
        }
        qsort(s,0,n-1);
        for(i=0;i<n;++i){
            cout<<s[i];
            if(i==n-1){
                cout<<endl;
            }
            else{
                cout<<" ";
            }
        }
    }
    return 0;
}

问题 D: 随机化快速排序

题目描述

使用Java或C++等语言中内置的随机函数实现随机化快速排序,在数组中随机选择一个元素作为分区的主元(Pivot)。

输入

多组样例输入,每组由一个一维整型数组组成。

输出

随机化快速排序之后的一维整型数组(升序排列)。

样例输入

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

样例输出

1 3 4 5 6 8
2 5 8 12 42

 

 

#include <bits/stdc++.h>
using namespace std;
int part(int s[],int a,int b){
    int i=a;
    int j=b+1;
    int x=s[a];
    while(1){
        while(s[++i]<x&&i<b);
        while(s[--j]>x);
        if(i>=j)
            break;
        swap(s[i],s[j]);
    }
    s[a]=s[j];
    s[j]=x;
    return j;
}
int randpart(int s[],int a,int b){
    int i=rand()%(b-a+1)+a;
    swap(s[i],s[a]);
    return part(s,a,b);
}
void rsort(int s[],int a,int b){
    if(a<b){
        int c=randpart(s,a,b);
        rsort(s,a,c-1);
        rsort(s,c+1,b);
    }
}
int main()
{
    int n;
    while(cin>>n){
        int s[n];
        //memset(s,0,n*sizeof(int));
        int i;
        for(i=0;i<n;i++){
            cin>>s[i];
        }
        rsort(s,0,n-1);
        for(i=0;i<n;++i){
            cout<<s[i];
            if(i==n-1){
                cout<<endl;
            }
            else{
                cout<<" ";
            }
        }
    }
    return 0;
}

问题 E: 第k大元素问题

题目描述

输入n个整数和一个正整数k(1<=k<=n),输出这些整数从大到小排序后的第k个。(要求时间复杂度为O(n),需使用随机化分区) 。

输入

多组数据输入,每组第一个数字为数组的长度n, 然后接下输入n个整数,最后输入整数k(1<=k<=n)。

输出

输出数组降序排序后的第k个整数。

样例输入

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

样例输出

3
6

 

//求第k大数还有其他的方法,可以用二分,时间复杂度是O(n),会在后面的""提到
#include <bits/stdc++.h>
using namespace std;
int part(int s[],int a,int b){
    int i=a;
    int j=b+1;
    int x=s[a];
    while(1){
        while(s[++i]<x&&i<b);
        while(s[--j]>x);
        if(i>=j)
            break;
        swap(s[i],s[j]);
    }
    s[a]=s[j];
    s[j]=x;
    return j;
}
int randpart(int s[],int a,int b){
    int i=rand()%(b-a+1)+a;
    swap(s[i],s[a]);
    return part(s,a,b);
}
void rsort(int s[],int a,int b){
    if(a<b){
        int c=randpart(s,a,b);
        rsort(s,a,c-1);
        rsort(s,c+1,b);
    }
}
int main()
{
    int n,i;
        int m;
    while(cin>>n){
        int a[n];
        for(i=0;i<n;i++){
            cin>>a[i];
        }
        cin>>m;
        rsort(a,0,n-1);
        cout<<a[n-m]<<endl;
    }
    return 0;
}

 问题 F: 前m大数

 

题目描述

给你n个整数,请按从大到小的顺序输出其中前m大的数。

输入

每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。

输出

对每组测试数据按从大到小的顺序输出前m大的数。

样例输入 Copy

5 3
3 -35 92 213 -644

样例输出 Copy

213 92 3
#include <bits/stdc++.h>
using namespace std;
int part(int s[],int a,int b){
    int i=a;
    int j=b+1;
    int x=s[a];
    while(1){
        while(s[++i]<x&&i<b);
        while(s[--j]>x);
        if(i>=j)
            break;
        swap(s[i],s[j]);
    }
    s[a]=s[j];
    s[j]=x;
    return j;
}
int randpart(int s[],int a,int b){
    int i=rand()%(b-a+1)+a;
    swap(s[i],s[a]);
    return part(s,a,b);
}
void rsort(int s[],int a,int b){
    if(a<b){
        int c=randpart(s,a,b);
        rsort(s,a,c-1);
        rsort(s,c+1,b);
    }
}
int main()
{
    int n,i;
        int m;
    while(cin>>n>>m){
        int a[n];
        for(i=0;i<n;i++){
            cin>>a[i];
        }
        rsort(a,0,n-1);
        for(i=n-1;i>=n-m;--i){
            cout<<a[i];
            if(i==n-m)
                cout<<endl;
            else
                cout<<" ";
        }
    }
    return 0;
}

 

 问题 G: Who's in the Middle

题目描述

FJ is surveying his herd to find the most average cow. He wants to know how much milk this 'median' cow gives: half of the cows give as much or more than the median; half give as much or less.

Given an odd number of cows N (1 <= N < 10,000) and their milk output (1..1,000,000), find the median amount of milk given such that at least half the cows give the same amount of milk or more and at least half give the same or less.

输入

* Line 1: A single integer N

* Lines 2..N+1: Each line contains a single integer that is the milk output of one cow.

输出

* Line 1: A single integer that is the median milk output.

样例输入 Copy

5
2
4
1
3
5

样例输出 Copy

3

提示

INPUT DETAILS: 
 Five cows with milk outputs of 1..5 
OUTPUT DETAILS: 
1 and 2 are below 3; 4 and 5 are above 3.

题意:求给出数字的中位数...

#include <bits/stdc++.h>
using namespace std;
int part(int s[],int a,int b){
    int i=a;
    int j=b+1;
    int x=s[a];
    while(1){
        while(s[++i]<x&&i<b);
        while(s[--j]>x);
        if(i>=j)
            break;
        swap(s[i],s[j]);
    }
    s[a]=s[j];
    s[j]=x;
    return j;
}
int randpart(int s[],int a,int b){
    int i=rand()%(b-a+1)+a;
    swap(s[i],s[a]);
    return part(s,a,b);
}
void rsort(int s[],int a,int b){
    if(a<b){
        int c=randpart(s,a,b);
        rsort(s,a,c-1);
        rsort(s,c+1,b);
    }
}
int main()
{
    int n,i;
        int m;
    while(cin>>n){
        int a[n];
        for(i=0;i<n;i++){
            cin>>a[i];
        }
        rsort(a,0,n-1);
        cout<<a[n/2]<<endl;
    }
    return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值