北航2020级算法分析与设计-C2

本文是一篇关于算法学习的博客,作者分享了几个不同难度的算法题目的解题思路和代码实现,包括寻找最匹配的魔杖、卡特兰数、公交座位调整、搬题策略、最大子数组和、二分查找优化等。通过这些实例,作者旨在帮助读者巩固基础,提升算法能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说在最开始的话

这篇博客仅仅是提供学习资料和我个人的复习使用,在学习算法的过程中代码还是要自己亲手打一遍,不要图方便直接复制粘贴代码。复制代码百害而无一利。

前言

写这个系列博客的初衷是学习算法的过程有些粗糙,对于各个算法的掌握也是不太熟练,再加上复习时苦于没有往年题目的痛苦。为了自己和学弟学妹在算法上能有所进步,开坑20级算法分析与设计。
本次更新C2 C2更多是对于数据结构和c语言基础的复习,涉及算法的部分不多,大家可以看一下自己的知识掌握如何。

A 这一刻我已等待许久

题目描述

众所周知,所有电子设备在霍格沃兹都会失去作用。因此 Alex 只要打开这封信,他就不用出题了。

他在信上了解到,他需要购买一件巫师袍,一只猫头鹰和一根魔杖。

Alex 走进奥利凡德魔杖店,被告知 “魔杖选择巫师”

人生而不同,魔杖会根据一个人的勇气,忠诚,智慧,野心的高低来选择合适的巫师

奥利凡德很轻松的就找到了 Alex 的四项属性值 a,b,c,d。

将魔杖标号,每一根魔杖对主人的要求也可以概括为这四项属性 Ai,Bi,Ci,Di
Alex 希望自己能够得到与自己契合度最高的魔杖,也就是使得 |a−Ai|+|b−Bi|+|c−Ci|+|d−Di| 最小。他应该买第几根魔杖呢?

对了,标号越大的魔杖价格也越高,因此契合度相同时, Alex 希望优先选购便宜的那个。

输入

第一行五个正整数 n,a,b,c,d
第二行 n 个正整数 A1,A2,⋯,An
第三行 n 个正整数 B1,B2,⋯,Bn
第四行 n 个正整数 C1,C2,⋯,Cn
第五行 n 个正整数 D1,D2,⋯,Dn
n≤1000, 属性值均在 [1,100] 范围内

输出

    输出一行表示答案

分析

	这个题目可以说很简单,直接放代码
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int A[1005];
int B[1005];
int C[1005];
int D[1005];
int main()
{
      
    int n,a,b,c,d,i,result,temp,min=0x7fffffff; 
    char ch;
    scanf("%d %d %d %d %d",&n,&a,&b,&c,&d);
    for(i=1;i<=n;i++)
    scanf("%d",&A[i]);
    for(i=1;i<=n;i++)
    scanf("%d",&B[i]);   
    for(i=1;i<=n;i++)
    scanf("%d",&C[i]);    
    for(i=1;i<=n;i++)
    scanf("%d",&D[i]);    
    for(i=1;i<=n;i++){
   
    	temp=abs(a-A[i])+abs(b-B[i])+abs(c-C[i])+abs(d-D[i]);
    	if(temp<min){
   
    	min=temp;
    	result=i;    		
		}

	}
	printf("%d",result);
	return 0;
}

B 卡特兰数

题目描述

二叉树是一种重要的数据结构。

有1个节点的二叉树有1种,有2个节点二叉树有2种,有3个节点的二叉树有5种,有n个节点的二叉树记为h(n)种,h(n)又被称为卡特兰数。

现在,给出多组数据,每一组数据会给出一个正整数n。对于每一组数据,请输出h(n)的值。

输入

第一行一个正整数T,表示数据组数。

接下来T行,每行一个正整数n。

输出

   对于每一行输入,输出h(n)的值。

分析

这个题目依旧难度不大,简单的递归即可
	
下面是我自己的代码
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
long long int h(int jie){
   
	if(jie==1)
	return 1;
	else
	return ((4*jie-2)*h(jie-1)/(jie+1));
}
int main()
{
      
    int n,i,jie; 
    long long int result;
    scanf("%d",&n);
    while(n--){
   
    	scanf("%d",&jie);
    	result=h(jie);
    	printf("%lld\n",result);
	}
	
	    
	return 0;
}

C 公交排序

题目描述

Marvolo 在国庆的时候出去玩了一天,但不幸的是他选择的交通工具是公交车:因为假期出游的原因,车上人满为患,连移动到车门口下车都十分困难。

Marvolo 想:大家在哪一站下车一开始是无序的,可不可以先在公交车上调整成有序的(也就是单调不降的),这样下车的时候就不用着急往前挤了?如果要调整的话,最少要调整几次呢?因为车上人很多,规定一次调整只能交换相邻两个人的顺序。

为了简化问题,你可以认为公交车上一共有n个人,第i个人要在第ai个站下车。最开头那个人站的位置是车门位置。

举个栗子,假如有3个人,这三个人分别在第3,1,2站下车。先让前两个人交换顺序,变成1,3,2,再让后两个人交换顺序,变成1,2,3,就可以调整成有序的,此时调整次数最少。。

输入

第一行一个正整数n,表示人数。

接下来一行,有n个正整数,第i个数表示ai。

输出

    输出一个整数,表示最少交换几次。

输入样例

5
1 3 4 5 2 

输出样例

3

分析

这个题目有些难度,需要用到mergesort二分算法。
但是仔细想一想换位置的过程,其实和二分的过程很像,看具体代码可能更容易理解,
下面是我自己的代码。
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int a[200005];
int L[500005];
int R[500005];
long long int count;
void megre(int a[],int p,int q,int r) {
   
	int n1, n2, i, j, k;
	n1 = q - p + 1;
	n2 = r - q;
	for (i = 1; i <= n1; i++){
   
		L[i] = a[p + i - 1];		
	}

	for (j = 1; j <= n2; j++){
   
		R[j] = a[q + j];			
	}

	L
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值