首页 > 编程语言 >2024年春季学期《算法分析与设计》练习5

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

时间:2024-03-31 22:32:04浏览次数:26  
标签:输出 int 样例 学期 2024 算法 数组 Copy 输入

问题 A: 随机数

题目描述

有一个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 <stdio.h>

int main() {  
    int T,a,b,m,n;
	while(scanf("%d",&T)!=EOF){
		for(int i=0;i<T;i++){
			scanf("%d%d",&a,&b);
			printf("%d %d\n",b-a,a);
		}
	}
    return 0;  
}

问题 B: 随机化快速排序

题目描述

使用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 <stdio.h>
#include<stdlib.h>

//生成随机数
int random(int p,int q){
	return rand()%(q-p+1)+p;
}

//交换
void swap(int a[],int i,int j){
	int t=a[i];
	a[i]=a[j];
	a[j]=t;
}

//分区
int partition(int a[],int p,int q){
	int x=a[p];
	int i=p,j;
	for(j=p+1;j<=q;j++){
		if(a[j]<=x){
			i++;
			swap(a,i,j);
		}
	}
	swap(a,p,i);
	return i;
}

//排序
void quick(int a[],int p,int q){
	if (p < q) { 
		int r = random(p,q);
		swap(a, q, r);
		r = partition(a, p, q);
		quick(a, p, r - 1);
		quick(a, r + 1, q);
	}
}

int main() {  
    int n;
    int a[100];
    while (scanf("%d", &n) == 1) {
        for (int i = 0; i < n; ++i) {
            scanf("%d", &a[i]);
        }
        quick(a, 0, n- 1);
        for (int i = 0; i <n; ++i) {
            printf("%d ", a[i]);
        }
        printf("\n");
    }
    return 0;  
}

问题 C: 第k小元素问题

题目描述

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

输入

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

输出

输出第k小元素的值。

样例输入 Copy
2 5 6 1 8 7 9
2
样例输出 Copy
2
#include <stdio.h>
#include <stdlib.h>

//交换
void swap(int a[],int i,int j){
	int t=a[i];
	a[i]=a[j];
	a[j]=t;
}

//分区
int partition(int a[],int p,int q){
	int x=a[p];
	int i=p,j;
	for(j=p+1;j<=q;j++){
		if(a[j]<=x){
			i++;
			swap(a,i,j);
		}
	}
	swap(a,p,i);
	return i;
}

int random(int a[], int p, int q) { 
	if(q>=p){
		int k =(int)(rand()%(q-p+1)+p); 
		swap(a, k, p);
		return partition(a, p, q);
	}
}

//找第K小元素
int quick(int a[],int s,int t,int k){
	if(s==t) return a[s];
	int i = random(a,s,t);
	int j = i-s+1;//左边个数
	if(k<=j) return quick(a,s,i,k);
	else return quick(a,i+1,t,k-j);
}

int main() {  
    int n,k;
    int a[1000];
	while(~scanf("%d",&a[0])){
		int i =1;
		while (scanf("%d",&a[i++])) {
			if(getchar()=='\n'){
				break;
			}
		}
		scanf("%d",&k);       
		printf("%d\n",quick(a,0,i-1,k));
    }
    return 0;  
}

问题 D: 找中位数

题目描述

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

输入

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

输出

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

样例输入 Copy
5
5 3 2 1 4
样例输出 Copy
3
#include <stdio.h>  
#include <stdlib.h>  
#define N 100000
  
// 交换  
void swap(int *a, int *b) {  
    int t = *a;  
    *a = *b;  
    *b = t;  
}  
  
// 分区  
int partition(int a[], int l, int h) {  
    int p = a[h];  
    int i = l - 1;  
    for (int j = l; j < h; j++) {  
        if (a[j] <= p) {  
            i++;  
            swap(&a[i],&a[j]);  
        }  
    }  
    swap(&a[i+1],&a[h]);  
    return i+1;
}  
  
// 快速选择 
int quick(int a[], int l, int h, int k) {  
    if (l == h) {  
        return a[l];  
    }  
  
    int p = partition(a, l, h);  
  
    if (k == p) {  
        return a[k];  
    } else if (k < p) {  
        return quick(a, l, p - 1, k);  
    } else {  
        return quick(a, p + 1, h, k);  
    }  
}  
  
// 计算中位数  
double find(int a[], int n) {  
    if (n%2==1) {  
        return (double)quick(a,0,n-1,n/2);  
    } else { 
        int m1 = quick(a,0,n - 1,n / 2 - 1);  
        int m2 = quick(a,0,n - 1,n / 2);  
        return (m1 + m2) / 2.0;  
    }  
}  
  
int main() {  
    int n,a[N];  
    while (scanf("%d",&n)!=EOF) { 
        for (int i = 0; i < n; i++) {  
            scanf("%d",&a[i]);  
        }  
        double m = find(a, n);  
        if (n % 2 == 0) {  
            printf("%.3f\n",m);  
        } else {  
            printf("%d\n",(int)m);  
        }
    }    
    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 <stdio.h>
#include <stdlib.h>

int main() {
    int n1, n2;
    while (scanf("%d",&n1)!=EOF) {
        int a1[100],a2[100],a[10000];
        for (int i = 0;i < n1;i++) {
            scanf("%d",&a1[i]);
        }
        scanf("%d",&n2);
        for (int i = 0; i < n2; i++) {
            scanf("%d",&a2[i]);
        }
        int i=0,j=0,q=0;
        while (i<n1 && j<n2) {
            if (a1[i] < a2[j]) {
                a[q++]=a1[i++];
            } else {
                a[q++]=a2[j++];
            }
        }
		while(i<n1) {
            a[q++]=a1[i++];
        }
        while(j<n2) {
            a[q++]=a2[j++];
        }
        for (i=0;i<n1+n2;i++) {
            printf("%d%c",a[i],(i==n1+n2-1)? '\n':' ');
        }
		printf("\n");
    }
    return 0;
}

问题 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 <stdio.h>
#include <stdlib.h>

void merge(int sr[],int tr[],int s,int m,int t){
	int i=s,j=m+1,k=s;
	while(i<=m&&j<=t){
		if(sr[i]<=sr[j]) tr[k++]=sr[i++];
		else tr[k++]=sr[j++];
	}
	while(i<=m) tr[k++]=sr[i++];
	while(j<=t) tr[k++]=sr[j++];
}
void mergeSort(int sr[],int tr[],int s,int t){
	if(s<t){
		int m=(s+t)/2;
		mergeSort(sr,tr,s,m);
		mergeSort(sr,tr,m+1,t);
		merge(sr,tr,s,m,t);
		for(int i=s;i<=t;i++){
			sr[i]=tr[i];
		}
	}
}
int main() {
    int n,sr[100000],tr[100000];
    while (scanf("%d",&n)!=EOF) {
		for(int i=0;i<n;i++){
			scanf("%d",&sr[i]);
		}
		mergeSort(sr,tr,0,n-1);
		for(int j=0;j<n;j++){
			printf("%d%c",tr[j],(j==n-1)?'\n':' ');
		}
	}
    return 0;
}

标签:输出,int,样例,学期,2024,算法,数组,Copy,输入
From: https://blog.csdn.net/qq_73820461/article/details/137201035

相关文章

  • 北京电子科技学院2024密码保密与网络对抗宣传赛WP
    个人赛20211108_俞振阳排名第六名解题思路ctf1签到题类型:Misc文件最后出现明显字符提示,尝试base64编码flag{ae9603a1-a905-f9be-5143-660bac605401}ctf5伪装者类型:Web尝试注入此ip值curl-H"X-Forwarded-For:1.1.1.1"http://39.106.48.123:13504/flag{4404......
  • 史上最全Java核心面试题(带全部答案)2024年最新版
    今天要谈的主题是关于求职,求职是在每个技术人员的生涯中都要经历多次。对于我们大部分人而言,在进入自己心仪的公司之前少不了准备工作,有一份全面细致面试题将帮助我们减少许多麻烦。在跳槽季来临之前,特地做这个系列的文章,一方面帮助自己巩固下基础,另一方面也希望帮助想要换工......
  • 小波特征提取算法代码
    functiontezhengtiqu%新归一化方法小波矩特征提取----------------------------------------------------------F=imread('a1.bmp');F=im2bw(F);F=imresize(F,[128128]);%求取最上点fori=1:128forj=1:128if(F(i,j)==1)ytop=i;......
  • 2024-03-31
    2024-03-31讲课提到的很有道理啊,确实很常见在窗口的星星里面就用到了还有一个小技巧求区间0的个数不好做有的时候满足所有数非负转化成求区间最小值是不是0和区间最小值的个数就行了这两天讲课的时候还经常提到·修改和查询的复杂度不平衡的时候,把他平衡会更优秀......
  • 解决一个有意思的抛硬币问题,计算连续两次正面所需次数的数学期望
    文章目录一、问题与分析二、基本的数学推导三、代码示例......
  • 上海大厂Android面试经历;华为+小米,阿里高级算法专家公开10份资料
    第三方库的源码,Glide、OkHttp和Retrofit问得比较多,MVC,MVP和MVVM开发模式优缺点。常用设计模式理解问得也多,大公司Binder驱动和虚拟机方面问得比较多。3.数据结构和算法,Java的常用集合和实现原理比如ArrayList,LinkedHashMap的实现原理,缓存淘汰策略,红黑树和二叉......
  • 毕业设计:基于卷积神经网络的短文本分类算法系统
    目录前言项目背景数据集设计思路更多帮助前言  ......
  • 代码随想录算法训练营第11天 | 栈和队列
    20.有效的括号遇到左括号入栈,遇到右括号弹出boolisValid(strings){ stack<char>kuohao; charc; for(chara:s){ switch(a) { case'(': case'{': case'[': kuohao.push(a); break; case')': case'......
  • 2024 python毕业设计(论文)- python毕设选题大全 - 选题指导精编版
    目录前言python毕设选题开题指导建议更多精选选题选题帮助最后前言大家好,这里是海浪学长毕设专题!大四是整个大学期间最忙碌的时光,一边要忙着准备考研、考公、考教资或者实习为毕业后面临的升学就业做准备,一边要为毕业设计耗费大量精力。学长给大家整理了计算机专......
  • q1-投资理财-2024.3.31
    q1-投资理财-2024.3.31​ 接上回,持有的徐工机械,一边下跌一边加仓,截止到5.86清仓想全仓做t,等第二天下跌下来再买入,没想到直接高开6个点,望尘莫及,亏死。​ 盈利的基本不去动了,亏损的等以后看看能不能想办法搞回来,传智资金到12-13左右就资金一直在流出,这玩应,我发现资金流入的很有......