「考研算法」

news2025/1/11 21:02:42

考研算法

前言

本系列文章涉及的算法内容,针对的是哈尔滨工业大学854科目。在本文中通过具体的算法题进行讲解相应算法。

今天涉及的算法主要有线性筛,十大排序中快速排序和归并排序。

后续会有动态规划的相关算法以及尝试模型的总结,如果对动态规划有兴趣的,可以看我之前的这篇文章,后边都是以这样的形式进行每个动态规划知识点的讲解。
链接如下:https://blog.csdn.net/qq_45992664/article/details/123341143?spm=1001.2014.3001.5502


一、线性筛算法

算法题目:筛质数

给定一个正整数 n,请你求出 1∼n中质数的个数。

输入格式

共一行,包含整数 n。

输出格式

共一行,包含一个整数,表示 1∼n中质数的个数。

数据范围

1 ≤ n ≤ 10^6

输入样例:

8

输出样例:

4

算法思路:

  1. 切记1不是质数
  2. 核心:把某一个合数用它的质因数进行筛走。

我们常见的筛法有:朴素筛法(O(LogN * N)),埃式筛法(O(N*log(logN)),线性筛法(O(N))。本文中选择时间复杂度最好的线性筛法。

算法代码:

#include <iostream>
using namespace std;
const int N = 1e6 + 5;
bool st[N];
int primes[N];
int cnt;
void getPrimes(int n){
    for(int i = 2; i <= n; ++i){
        if(!st[i]){
            primes[cnt++] = i;//把质数添加进去
        }
        //for循环每次进行从0开始到primes[j] * i ~ n,最大到n
        for(int j = 0; primes[j] <= n / i; ++j){
            st[primes[j] * i] = true;
            if(i % primes[j] == 0){
                break;
            }
        }
        // 1. 如果 i % primes[j] == 0, 说明primes[j]是i的最小质因子,primes[j]一定是primes[j] * i  的最小质因子。
        // 2. 如果 i % primes[j] != 0, 说明primes[j]一定小于i的所有质因子,primes[j]一定是primes[j] * i 的最小质因子。
    }
}
int main(){
    int n;
    scanf("%d", &n);
    getPrimes(n);
    printf("%d\n", cnt);
    return 0;
}

今天的算法除了线性筛比较难点,剩下的排序算法都很简单,直接上代码,不再进行注释。


二、快速排序

算法题目: 快速排序

给定你一个长度为 n的整数数列。

请你使用快速排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式

输入共两行,第一行包含整数 n。

第二行包含 n个整数(所有整数均在 1∼10^9 范围内),表示整个数列。

输出格式

输出共一行,包含 n个整数,表示排好序的数列。

数据范围

1≤n≤100000

输入样例:

5
3 1 2 4 5

输出样例:

1 2 3 4 5

算法代码:

java版本

import java.util.Scanner;

public class Main {
    public static void quicksort(long a[],int l,int r){
        if(l >= r)return;
        int i = l-1,j = r + 1;
        long x = a[(l + r)/2];
        while(i<j){
            do i++;while (a[i]<x);
            do j--;while (a[j]>x);
            if(i<j)
                swap(a,i,j);
        }
        quicksort(a,l,j);
        quicksort(a,j+1,r);
    }
    public static void swap(long[] a,int i,int j){
        long tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        long[] arr = new long[n];
        for (int i = 0;i < n;i++){
            arr[i] = sc.nextInt();
       }
        quicksort(arr,0,n-1);
        for (int i = 0;i < n;i++){
            System.out.print(arr[i] + " ");
        }
    }
}

C++版本

#include<iostream>

using namespace std;

const int N=1e6 + 10;
int a[N];
void  quick_sort(int l,int r)
{
    if(l>=r) return ;
    int i=l-1,j=r+1,x=a[l+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(l,j);
    quick_sort(j+1,r);
}
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++) scanf("%d",&a[i]);
    quick_sort(0,n-1);
    for(int i=0;i<n;i++) printf("%d ",a[i]);
    return 0;
}

三、归并排序

注:由归并排序衍生出的小和问题,逆序对的数量的问题,后边会进行一一讲解。

算法题目:归并排序

给定你一个长度为 n的整数数列。

请你使用快速排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式

输入共两行,第一行包含整数 n。

第二行包含 n个整数(所有整数均在 1∼10^9 范围内),表示整个数列。

输出格式

输出共一行,包含 n个整数,表示排好序的数列。

数据范围

1≤n≤100000

输入样例:

5
3 1 2 4 5

输出样例:

1 2 3 4 5

算法代码:

java版本

import java.io.*;
import java.util.Scanner;

public class Main {
    public static void mergeSort(long[] arr){
        mergeSort(arr, 0, arr.length - 1);
    }
    public static void mergeSort(long[] arr, int l, int r){
        if(l >= r){
            return;
        }
        int mid = l + ((r - l) >> 1);
        mergeSort(arr, l, mid);
        mergeSort(arr, mid + 1, r);

        long[] help = new long[r - l + 1];
        int i = 0;
        int p1 = l;
        int p2 = mid + 1;
        while(p1 <= mid && p2 <= r){
            help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        while(p1 <= mid){
            help[i++] = arr[p1++];
        }
        while(p2 <= r){
            help[i++] = arr[p2++];
        }
        for(i = 0; i < help.length; ++i){
            arr[l + i] = help[i];
        }
    }
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
        String[] str1 = in.readLine().split(" ");
        int n = Integer.parseInt(str1[0]);
        //int k = Integer.parseInt(str1[1]);
        long[] arr = new long[n];
        String[] str2 = in.readLine().split(" ");
        for(int i = 0; i < n; i++){
            arr[i] = Integer.parseInt(str2[i]);
        }
        mergeSort(arr, 0, n - 1);
        for(int i = 0; i < n; i++){
            System.out.print(arr[i] + " ");
        }
        out.flush();
        out.close();
        in.close();
    }
}

C++版本

#include <algorithm>
#include <iostream>
using namespace std;
void merge_sort(int a[], int l, int r){
    if(l >= r){
        return;
    }
    int mid = l + ((r - l) >> 1);
    merge_sort(a, l, mid);
    merge_sort(a, mid + 1, r);
    int help[r - l + 1];
    int i = 0;
    int p1 = l;
    int p2 = mid + 1;
    while(p1 <= mid && p2 <= r){
        help[i++] = a[p1] < a[p2] ? a[p1++] : a[p2++];
    }
    while(p1 <= mid){
        help[i++] = a[p1++];
    }
    while(p2 <= r){
        help[i++] = a[p2++];
    }
    for(p1 = l, p2 = 0; p1 <= r; p1++, p2++){
        a[p1] = help[p2];
    }
}
int main(){
    int n;
    cin >>n;
    int a[n];
    for(int i = 0; i < n; i++){
        cin >> a[i];
    }
    merge_sort(a, 0, n - 1);
    for(int i = 0; i < n; i++){
        cout<< a[i] << " ";
    }
    return 0;
}

最后介绍一个有意思的算法:高精度阶乘

算法题目: 高精度阶乘

随意输入一个n,要求返回n的阶乘。

一、代码如下:

import java.util.Scanner;

public class LargeIntegerFactorial {
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        long[] ans = new long[10001000];
        long n = sc.nextLong();
        ans[0] = 1;

        int l = 0;
        long num = 0;
        for(int i = 1; i<=n;++i)
        {
            num = 0;
            for(int j = 0; j <= l; j++)
            {
                num = num + ans[j] * i;
                ans[j] = num % 10;
                num /= 10;
            }
            while(num != 0)
            {
                ans[++l] =num % 10;
                num /= 10;
            }
        }
        for(int i = l; i >= 0; --i)
        {
            System.out.print(ans[i]);
        }
        return;
    }
}



#### 代码解析:

```java
	我们接下来把n设置为4,进行代码的实例演示以及解析
	{
		long[] ans = new long[10001000];//定义答案数组
		n = 4;//设置指定数字为4
		ans[0] = 1;	//将答案数组的第一位设置为1
	    int l = 0;//定义变量l,用来记录n!的数字有多少位
	    long num = 0;//定义变量num
	    for(int i = 1; i<=n;++i)//核心代码,将在下边进行实例解析
	    {
	        num = 0;
            for(int j = 0; j <= l; j++)
            {
                num = num + ans[j] * i;
                ans[j] = num % 10;
                num /= 10;
            }
            while(num != 0)
            {
                ans[++l] =num % 10;
                num /= 10;
            }	   
       }
       
       
       {
       		当i == 1时,j == 0, j <= l (0 <= 0), num = 0;
       			num = num + ans[0] * i = 0 + 1 * 1 = 1;
       			ans[0] = num % 10 = 1 % 10 = 1;
       			num = num / 10 = 1 / 10 = 0;
       			
       		当i == 2时,j == 0,j <= l (0 <= 0),num = 0;
       			num = num + ans[0] * i = 0 + 1 * 2 = 2;
       			ans[0] = num % 10 = 2 % 10 = 2;
       			num = num / 10 = 2 / 10 = 0;
       			
       		当i == 3时,j == 0,j <= l (0 <= 0),num = 0;
       			num = num + ans[0] * i = 0 + 2 * 3 = 6;
       			ans[0] = num % 10 = 6 % 10 = 6;
       			num = num / 10 = 6 / 10 = 0;
       			
       		当i == 4时,j == 0,j <= l (0 <= 0),num = 0;
       			num = num + ans[0] * i = 0 + 6 * 4 = 24;
       			ans[0] = num % 10 = 24 % 10 = 4;
       			num = num / 10 = 24 / 10 = 2;
       			进入while循环,
       				num = 2 != 0;
       				ans[++l] = num % 10 = 2 % 10 = 2;(此时l == 1);
       				ans[1] = 2;
       				num = num / 10 = 2 / 10 = 0;
       		
       		当i == 5时,j == 0,j <= l (0 <= 1),num = 0;
       			num = num + ans[0] * i = 0 + 4 * 5 = 20;
       			ans[0] = num % 10 = 20 % 10 = 0;
       			num = num / 10 = 2;
       		当i == 5时,j == 1,j <= l (1 <= 1),num = 2;
       			num = num + ans[1] * i = 2 + 2 * 5 = 12;
       			ans[1] = num % 10 = 12 % 10 = 2;
       			num = num / 10 = 12 / 10 = 1;
       			进入while循环,
       				num = 1 != 0;
       				ans[++l] = num % 10 = 1 % 10 = 1;(此时l == 2);
       				ans[2] = 1;
       				num = num / 10 = 0;
       		结束。
       }
	}
	
代码测试:

1.n = 1000

在这里插入图片描述

1000! = 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

计算时间是非常快的,大家可以对照这个链接下的1000!,来看看程序是否算对了,我大致看了下,没有问题。

链接如下:https://www.haomeili.net/JieCheng?JieCheng=1000

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/379834.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Java·算法·中等]LeetCode17. 电话号码的字母组合

每天一题&#xff0c;防止痴呆题目示例分析思路1题解1分析思路2题解2题目 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。…

本科毕业设计-基于ORB SLAM3的多从机SLAM导航系统

耗时&#xff1a;两个月 需求&#xff1a;多从机协作 多地图系统 稠密建图 定位 导航 硬件&#xff1a;二个D435 一台X86主机&#xff08;CPU:13600kf 内存:32G&#xff09; X86主机环境&#xff1a;ubuntu18.04 opencv3.2 ROS1 主要代码参考&#xff1a;ORB-SLAM3 主要调用…

【CNN】FractalNet——与DenseNet有异曲同工之妙

FractalNet论文名称&#xff1a;FractalNet: Ultra-Deep Neural Networks without Residuals FractalNet论文下载链接&#xff1a; FractalNet&#xff08;分型网络&#xff09;&#xff0c;2016年Gustav Larsson首次提出。 &#xff08;1&#xff09;分形网络不像resNet那样…

嵌入式 Linux 文件IO操作

目录 Linux 文件操作 1 Linux 系统环境文件操作概念 2 缓冲 IO 文件操作 1 文件的创建&#xff0c;打开与关闭 fopen 函数函数 2 freopen 函数 3、fdopen函数 4、fclose函数 5、格式化读写 6、单个字符读写 7、文件定位 8、标准目录文件 9、非缓冲IO文件操作 Linux 文…

十二、MyBatis的高级映射及延迟加载

1 数据库表的准备 准备数据库表&#xff1a;一个班级对应多个学生。班级表&#xff1a;t_clazz。学生表&#xff1a;t_stu 2 环境搭建 创建模块 打包方式&#xff1a;jar 引入依赖&#xff1a;mybatis依赖、mysql驱动依赖、junit依赖、logback依赖 配置文件&#xff1a;…

C#/.net程序调用python

C#/.net程序调用python C#的优势在于window下的开发&#xff0c;不仅功能强大而且开发周期短。而python则有众多的第三方库&#xff0c;可以避免自己造轮子&#xff0c;利用C#来做界面&#xff0c;而具体实现使用python来实现可以大大提高开发效率。本文介绍如何使用pythonnet…

Kubernetes初始化容器

初始化容器 之前了解了容器的健康检查的两个探针&#xff1a;liveness probe&#xff08;存活探针&#xff09;和readiness probe&#xff08;可读性探针&#xff09;的使用方法&#xff0c;我们说在这两个探针是可以影响容器的生命周期的&#xff0c;包括我们之前提到的容器的…

如何或者无插件Web页面监控播放软件LiveNVR的固定视频流地址,实现大屏上墙、播放、视频分析等目的

1、LiveNVR介绍 LiveNVR的安防监控的视频直播&#xff0c;可以按标准的Onvif/RTSP协议接入监控设备&#xff0c;也可以通过海康、大华、天地伟业等厂家私有SDK接入监控&#xff0c;实现web页面的播放和录像回放。 可以分发HTTP-FLV、WS-FLV、WebRTC、RTMP、HLS(M3U8)、RTSP等多…

Linux安装Tomcat9

默认Linux已经安装了JDK 并且已经配置好了环境变量 下载链接 Tomcat9 下载完成如下图 &#xff0c;这个下载完成需要看一下&#xff0c;有的包里bin目录内缺少bootstrap.jar文件&#xff0c;因此下载包的时候要看看bin目录下的是不是有这个文件&#xff0c;如果没有启动Tomcat…

CHAPTER 1 Linux 集群

集群1 集群介绍2 集群分类1. 高可用性集群&#xff08;High Availability Cluster&#xff09;HA2. 负载均衡集群&#xff08;Load Balance Cluster&#xff09;LB3. 高性能集群&#xff08;High Performance Computing Cluster&#xff09;HPC3 HA集群逻辑架构1. 信息层/基础架…

Qt页面菜单栏、工具栏、状态栏

1、菜单栏 QMenu *editMenu ui->menuBar->addMenu("编辑(&E)");2、编辑菜单栏及工具栏内容 QAction *action_copy editMenu->addAction(QIcon("copy.png"),QString("复制(&c)"));action_copy->setShortcut(QKeySequence(…

数学建模竞赛的一些心得体会

1.数学建模经验首先简要的介绍一下我的情况。数学建模我也是在大一暑假开始接触的&#xff0c;之前对其没有任何的了解。我本身对数学也有相对较厚的兴趣&#xff0c;同时我也是计算机专业的学生&#xff0c;因此&#xff0c;我觉得我可参加数学建模的这个比赛。大一的暑假参加…

Linux->进程终止和等待

目录 1. 进程终止场景 1.1 进程退出码 1.2 进程常见退出方式 2. 进程等待 2.1 进程等待的必要性 2.2 进程等待的方式 wait()方式 waitpid()方式 options参数 status参数 1. 进程终止场景 代码运行完毕&#xff0c;结果正确 代码运行完毕&#xff0c;结果不正确 代码异…

【编程架构实践】关于技术栈和架构

架构是什么&#xff1f;老生常谈了。那就看看ChatGPT怎么说&#xff1a;软件架构是软件工程师在设计一个软件系统时&#xff0c;定义系统架构结构的一种科学方法。它指的是软件系统在软件工程师关注功能、性能和安全等质量属性的条件下&#xff0c;组织系统的方式。换句话说&am…

Flask源码篇:wsgi、Werkzeug与Flask启动工作流程

目录1 wsgi介绍2 使用wsgi实现一个web应用3 Werkzeug介绍4 Flask工作流程分析&#xff08;1&#xff09;创建Flask app&#xff08;2&#xff09;启动Falsk app&#xff08;3&#xff09;分析run_simple方法&#xff08;4&#xff09;分析make_server方法&#xff08;5&#xf…

内容分发网络

介绍 CDN 内容分发网络&#xff08;英语&#xff1a;Content Delivery Network 或 Content Distribution Network&#xff0c;缩写&#xff1a;CDN&#xff09;是建立并覆盖在承载网上&#xff0c;由不同区域的服务器组成的分布式网络。将源站资源缓存到全国各地的边缘服务器&…

【数据库视图】简单学习视图,了解一些视图的简单功能

前言&#xff1a; 大家好&#xff0c;我是良辰丫&#x1f345;&#x1f345;&#x1f345;&#xff0c;今天我想带大家去了解一下数据库的视图,虽然视图这个东西在很多地方(各种公司以及项目)已经不再用了,但是许多大学生在考试的时候涉及,&#x1f6f4;&#x1f6f4;&#x1f…

【c++】STL常用容器5—list容器

文章目录list基本概念list构造函数list赋值和交换list大小操作list插入和删除list数据存取list反转和排序list基本概念 功能&#xff1a;将数据进行链式存储。 链表&#xff08;list&#xff09;是一种物理存储单元上非连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链…

京东物流实时风控实践

摘要&#xff1a;本文整理自京东风控数据产品组架构师周文跃&#xff0c;在 FFA 2022 实时风控专场的分享。本篇内容主要分为六个部分&#xff1a;1. 京东物流业务介绍2. 物流风控场景概括3. 物流风控平台建设4. Flink 赋能5. 技术挑战6. 未来规划Tips&#xff1a;点击「阅读原…

操作系统权限提升(二十)之Linux提权-计划任务提权

系列文章 操作系统权限提升(十八)之Linux提权-内核提权 操作系统权限提升(十九)之Linux提权-SUID提权 计划任务提权 计划任务提权原理 linux计划任务提权是因为权限配置不当&#xff0c;计划任务以root权限运行&#xff0c;低权限的用户可以修改计划任务的文件&#xff0c;…