当前位置: 首页 > news >正文

2025年春季学期《算法分析与设计》练习4

目录

A: 快速排序

 B: 随机数

C: 随机化快速排序

 D: 第k小元素问题

 E: 找中位数

F: 数的划分

G: 带分数

 H: 最大质因数


A: 快速排序

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

输入

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

输出

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

样例输入 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 <iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N];
void quick_sort(int a[], int l, int r)
{
  if (l >= r)
    return;
  int x = a[(l + r + 1) / 2], i = l - 1, j = r + 1;
  while (i < j)
  {
    do
    {
      i++;
    } while (a[i] < x);
    do
    {
      j--;
    } while (a[j] > x);
    if (i < j)
      swap(a[i], a[j]);
  }
  quick_sort(a, l, i - 1);
  quick_sort(a, i, r);
}
int main()
{
  int n;
  while (~scanf("%d", &n))
  {
    for (int i = 0; i < n; i++)
      scanf("%d", &a[i]);
    quick_sort(a, 0, n - 1);
    for (int i = 0; i < n; i++)
      printf("%d ", a[i]);
    cout << endl;
  }
  return 0;
}

 B: 随机数

有一个rand(n)的函数,它的作用是产生一个在[0,n)的随机整数。现在有另外一个函数,它的代码如下:

int random(int n, int m)

{

         return rand(n)+m;

}

显而易见的是函数random(n,m)可以产生任意范围的随机数。现在问题来了,如果我想要产生范围在[a,b)内的一个随机数,那么对应的n,m分别为多少?

输入

输入的第一行为一个正整数T (T<=1000),表示一共有T组测试数据。

对于每组测试数据包含两个整数a,b (a<=b)。

输出

对于每组测试数据,输出一行包含两个整数n和m,两个整数中间有一个空格分隔。

样例输入 Copy
2
0 5
1 4
样例输出 Copy
5 0
3 1
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int N =1e4 +5;
const int M =1e9 +7;
const int inf =0x3fffffff;
void solve(){
    int n,a,b;
    cin>>n;
    while(n--){
        cin>>a>>b;
        cout<<b-a<<" "<<a<<"\n";
    }
}
int main() {
    ios::sync_with_stdio(0);cin.tie(0);
    //int t;cin>>t;while(t--)
    solve();
    return 0;
}

C: 随机化快速排序

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

输入

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

输出

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

样例输入 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 <iostream>
using namespace std;
const int N = 100002;
int a[N];
void quick_sort(int q[], int l, int r)
{
  if (l >= r)
    return;
  int m = rand() % (r - l + 1) + l;
  swap(q[l], q[m]);
  int x = q[l];
  int i = l - 1, j = r + 1;
  while (i < j)
  {
    do
      i++;
    while (q[i] < x);
    do
      j--;
    while (q[j] > x);
    if (i < j)
      swap(q[i], q[j]);
  }
  quick_sort(q, l, j);
  quick_sort(q, j + 1, r);
}
int main()
{
  int n;
  while (~scanf("%d", &n))
  {
    for (int i = 0; i < n; ++i)
      scanf("%d", &a[i]);
    quick_sort(a, 0, n - 1);
    for (int i = 0; i < n; ++i)
      cout << a[i] << " ";
    cout << endl;
  }
  return 0;
}

 D: 第k小元素问题

输入一个整数数组,请求出该数组的第k小元素。要求时间复杂度为O(n)。

输入

每组输入包括两行,第一行为一个整数数组,两个数字之间用空格隔开;第二行为k值。数组中元素个数小于1000。

输出

输出第k小元素的值。

样例输入 Copy
2 5 6 1 8 7 9
2
样例输出 Copy
2
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int N =1e3 +5;
const int M =1e9 +7;
const int inf =0x3fffffff;
int a[N];
int k;
int fun(int l,int r,int k){
    if(l==r){
        return a[l];
    }
    int i=l;
    for(int j=l+1;j<=r;j++){
        if(a[j]<=a[l]){
            swap(a[++i],a[j]);
        }
    }
    swap(a[i],a[l]);
    int m=i-l+1;
    if(k<=m){
        fun(l,i,k);
    }
    else{
        fun(i+1,r,k-m);
    }
}
void solve(){
    int n=0;
    char c,cc;
    while(cin>>a[0]){
        scanf("%c",&c);
        if(c!='\n'){
            for(n=1;;n++){
                cin>>a[n];
                scanf("%c",&cc);
                if(cc=='\n'){
                    break;
                }
            }
        }
        int k;
        cin>>k;
        cout<<fun(0,n,k)<<"\n";
    }
}
int main() {
    //ios::sync_with_stdio(0);cin.tie(0);
    //int t;cin>>t;while(t--)
    solve();
    return 0;
}

 E: 找中位数

请设计一个算法,不排序,快速计算出一个无序数列的中位数。 时间复杂度要求为O(n)。
如果有奇数个元素,中位数则是数组排序后最中间的那个数字。
如果是偶数个元素,中位数则是数组排序后最中间两个元素的平均值。

输入

有多组输入,每组输入的第一行为n(1<=n<=1e5),表示该数列的元素个数。
第二行为n个整数组成的无序数列

输出

每组样例输出一行,表示该无序数列的中位数。
若为偶数,请保留三位小数
若为奇数,直接输出

样例输入 Copy
5
5 3 2 1 4
样例输出 Copy
3
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cmath>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <map>
#include <iomanip>
#include <queue>
#define ll long long
#define MM 0x3f3f3f3f
#define pii pair<int, int>
#define pll pair<long long, long long>
using namespace std;
const int N = 1e3 + 5;
const int P = 131;
const int MOD=1e9+7;
const double PI = acos(-1.0);
//int dx[] = {0, 0, -1, 1,-1, -1, 1, 1};
//int dy[] = {1, -1, 0, 0,1, -1, 1, -1};
int n;
void fun(vector<int>& a){
    nth_element(a.begin(),a.begin()+n/2,a.end());
    if(n%2==1){
        cout<<a[n/2]<<"\n";
    } 
    else{
        nth_element(a.begin(),a.begin()+n/2-1,a.end());
        printf("%.3lf\n",0.5*(a[n/2-1]+a[n/2]));
    }
}
void solve(){
    while(cin>>n){
        vector<int>a(n);
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        fun(a);
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    solve();
    return 0;
}

F: 数的划分

使用递归编写一个程序,求一个正整数n的所有划分个数。
例如,输入3,输出3;输入4,输出5。

输入

多组输入,每一组是一个正整数n。

输出

输出划分数。

样例输入 Copy
3
4
样例输出 Copy
3
5
#include<iostream>
using namespace std;
int fun(int n,int m)
{
    if (n == 1 || m == 1)
        return 1;
    if (n > m)
        return fun(n - m, m) + fun(n, m - 1);
    else
        if (n < m)
            return fun(n, n);
        else
            return fun(n, n-1)+1;
}
int main()
{
    int n;
    while (cin >> n)
        cout << fun(n,n) << endl;
    return 0;
}

G: 带分数

100可以表示为带分数的形式,如100 = 3+ 69258/714,还可以表示为100 = 82 + 3546/197。
注意,在上述带分数的形式中,数字1,2,3,4,5,6,7,8,9均出现一次并只能出现一次。
类似这种带分数形式,100一共有11种表示方法。

输入

单组输入。
输入一个不超过10000的正整数N。

输出

输出该数字用1-9九个数字不重复且不遗漏地组成带分数形式表示的全部方法的数量。

样例输入 Copy
100
样例输出 Copy
11
#include <stdio.h>
#include <string.h>
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int fun(int l, int r) {
    int s = 0;
    for (int i = l; i <= r; i++) {
        s = s * 10 + a[i];
    }
    return s;
}
void swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}
int next_permutation(int *arr, int n){
    int i = n - 2;
    while (i >= 0 && arr[i] >= arr[i + 1]) i--;
    if (i < 0) return 0;
    int j = n - 1;
    while (arr[j] <= arr[i]) j--;
    swap(&arr[i], &arr[j]);
    int left = i + 1, right = n - 1;
    while (left < right) {
        swap(&arr[left], &arr[right]);
        left++;
        right--;
    }
    return 1;
}
void solve() {
    int n;
    scanf("%d", &n);
    int s = 0;
    do {
        for (int i = 0; i < 6; i++) {
            for (int j = i + 1; j <= 7; j++) {
                int x = fun(0, i);
                int y = fun(i + 1, j);
                int z = fun(j + 1, 8);
                if (y % z == 0 && x + y / z == n) {
                    s++;
                }
            }
        }
    } while (next_permutation(a, 9));
    printf("%d\n", s);
}
int main() {
    solve();
    return 0;
}

 H: 最大质因数

自然数中任何一个合数都可以表示成若干个质因数乘积的形式,如果不考虑因数的顺序,那么这个表示形式是唯一的。
把一个合数分解成几个质数相乘的形式,叫做分解质因数,这几个质数就叫做这个合数的质因数。例如,60=2×2×3×5,2024=2×2×2×11×23。所有的质因数中最大者称为最大质因数。
请编写一个程序输出一个合数的最大质因数。

输入

单组输入。
输入一个不超过10^9的合数N。

输出

输出该合数的最大质因数。

样例输入 Copy
2024
样例输出 Copy
23
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int M =1e9 +7;
const int N =1e2 +5;
int a[N];
void solve(){
    int n;
    cin>>n;
    int m=0;
    for(int i=2;i<=sqrt(n);i++){
        if(n%i==0){
            a[++m]=i;
            while(n%i==0){
                n/=i;
            }
        }
    }
    if(n>1){
        a[++m]=n;
    }
    cout<<a[m]<<"\n";
}
int main() {
    cin.tie(0)->sync_with_stdio(false);
    solve();
    return 0;
}

 

相关文章:

  • 碰一碰发视频saas系统技术源头一站式开发文档
  • Tomcat虚拟主机配置详解:Centos环境下多域名部署(详细教程!)
  • 输入输出 数组 冒泡排序举例
  • 基于Spring Boot的大学校园生活信息平台的设计与实现(LW+源码+讲解)
  • 机器学习之支持向量机(SVM)算法详解
  • docker 的volumes如何清理
  • SpringBoot的启动原理?
  • ubuntu中的ens33网卡在ifconfig中被默认关闭了?
  • c语言笔记 存储期
  • Topaz Photo AI for Mac v3.5.2图像质量增强 支持M、Intel芯片
  • python-列表的操作以及切片
  • 异常(完)
  • 计算GPS点之间距离(JS实现)
  • 从C语言开始的C++编程生活(1)
  • 第二十七篇 数据仓库与维度建模指南:从理论到实战的进阶之路
  • 无需OpenAI API运行OpenManus!
  • docker和k8s区别详解
  • NLP高频面试题(五)——BERT的基本结构介绍、预训练任务、下游任务
  • Business processes A bridge to SAP and a guide to SAP TS410 certification
  • 资源文件逆向与界面篡改技术
  • 西安做网站 怎样备案/新营销模式有哪些
  • 网站建设与管理实训报告/最好的搜索引擎排名
  • 青岛做网站哪家优化好/建站公司最新报价
  • 企业网站关于我们/深圳网站seo
  • 免费网站建设排行榜/优化seo教程技术
  • 关于做网站的外语文献书名/百度联盟点击广告赚钱