算法回忆录(2)

news2024/10/1 9:41:01

6.输入一个非递减排列的整数数组nums,和一个目标值target。请找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值target,则输出0,0。请设计一个时间复杂度为0(log n)的算法解决此问题。

输入包括两行,第一行输入两个整数,分别表示数组的长度和target,第二行输入数组nums。输出为一个整数。

例如输入:

6 8

5 7 7 8 8 10

则输出: 4 5

若输入:

6 9

5 7 7 8 8 10

则输出: 0 0

#include <stdio.h>  
  
// 二分查找的变种,用于找到目标值的左边界  
int findLeftBound(int* nums, int numsSize, int target) {  
    int left = 0, right = numsSize - 1;  
    int leftBound = -1; // 初始化左边界为-1,表示未找到  
    while (left <= right) {  
        int mid = left + (right - left) / 2;  
        if (nums[mid] >= target) {  
            right = mid - 1; // 尝试在左半部分查找  
            leftBound = mid; // 更新左边界  
        } else {  
            left = mid + 1;  
        }  
    }  
    return leftBound;  
}  
  
// 二分查找的变种,用于找到目标值的右边界  
int findRightBound(int* nums, int numsSize, int target) {  
    int left = 0, right = numsSize - 1;  
    int rightBound = -1; // 初始化右边界为-1,表示未找到  
    while (left <= right) {  
        int mid = left + (right - left) / 2;  
        if (nums[mid] <= target) {  
            left = mid + 1; // 尝试在右半部分查找  
            rightBound = mid; // 更新右边界  
        } else {  
            right = mid - 1;  
        }  
    }  
    return rightBound;  
}  
  
int main() {  
    int numsSize, target;  
    scanf("%d %d", &numsSize, &target);  
    int nums[numsSize];  
    for (int i = 0; i < numsSize; i++) {  
        scanf("%d", &nums[i]);  
    }  
  
    int leftBound = findLeftBound(nums, numsSize, target);  
    int rightBound = findRightBound(nums, numsSize, target);  
  
    // 如果左边界仍为-1,说明未找到目标值  
    if (leftBound == -1) {  
        printf("0 0\n");  
    } else {  
        printf("%d %d\n", leftBound + 1, rightBound + 1); // 数组索引从0开始,输出从1开始  
    }  
  
    return 0;  
}

解释和步骤:

  1. 函数 findStartIndex

    • 使用修改版的二分查找来找到目标值在数组中的起始位置。
    • 初始化左右边界,然后在循环中根据中间元素与目标值的比较调整左右边界。
    • 如果找到目标值,更新 start 并继续向左查找。
  2. 函数 findEndIndex

    • 使用同样的修改版二分查找来找到目标值在数组中的结束位置。
    • 初始化左右边界,然后在循环中根据中间元素与目标值的比较调整左右边界。
    • 如果找到目标值,更新 end 并继续向右查找。
  3. 主函数 main

    • 输入数组的长度和目标值。
    • 输入排序后的整数数组。
    • 调用 findStartIndexfindEndIndex 函数找到目标值的起始位置和结束位置。
    • 如果找到了起始位置和结束位置,则输出它们;否则输出 "0 0" 表示目标值不存在于数组中。

运行结果:

7. 残缺棋盘是一个有2k×2k (k≥1)个方格的棋盘,其中恰有一个方格残缺。 下图给出k=1时各种可能的残缺棋盘,其中残缺的方格用阴影表示。

图中的棋盘称作“三格板”,残缺棋盘问题就是用这四种三格板覆盖更大的残缺棋盘。在覆盖中要求: 1)两个三格板不能重叠 2)三格板不能覆盖残缺方格,但必须覆盖其他所有方格 编程输入k及残缺格的坐标,求残缺棋盘覆盖方法。 输入:三个整数,分别表示k值和残缺格的坐标; 输出:2k×2k矩阵,具体数值为覆盖的序号。

#include<stdio.h>
#include<math.h>
void TileBoard(int tr,int tc,int dr,int dc,int size);
void OutputBoard(int size);
int tile=1;
int Board[1025][1025];
int main()
{
 int n,a,b;
 scanf("%d",&n);
 int sum;
 sum=pow(2,n);
 scanf("%d %d",&a,&b);
 Board[n][n]=0;
 TileBoard(0,0,a,b,sum);
 OutputBoard(sum);
 return 0;
}
void TileBoard(int tr,int tc,int dr,int dc,int size)
{
 if(size==1) return;
 int t=tile++,
 s=size/2;
 if(dr<tr+s&&dc<tc+s)
 TileBoard(tr,tc,dr,dc,s);
 else
 {
 Board[tr+s-1][tc+s-1]=t;
 TileBoard(tr,tc,tr+s-1,tc+s-1,s);
 }
 if(dr<tr+s&&dc>=tc+s)
TileBoard(tr,tc+s,dr,dc,s);
 else 
 {
 Board[tr+s-1][tc+s]=t;
 TileBoard(tr,tc+s,tr+s-1,tc+s,s);
 }
 if(dr>=tr+s&&dc<tc+s)
 TileBoard(tr+s,tc,dr,dc,s);
 else
 { 
 Board[tr+s][tc+s-1]=t;
 TileBoard(tr+s,tc,tr+s,tc+s-1,s);
 }
 if(dr>=tr+s&&dc>=tc+s)
TileBoard(tr+s,tc+s,dr,dc,s);
 else 
 {
 Board[tr+s][tc+s]=t;
 TileBoard(tr+s,tc+s,tr+s,tc+s,s);
 }
}
 void OutputBoard(int size)
 {
 for(int i=0;i<size;i++)
 {
 for(int j=0;j<size;j++){
 printf("%-3d",Board[i][j]);
 }
 printf("\n");
 }
 printf("end");
 }

 运行结果:

8. 活动安排问题求解: 假设某社团某一天要组织n个活动E={1,2,3...n},其中每个活动都要求使用同一礼堂,而且在同一时间内只有一个活动能使用这个礼堂。每个活动i都有一个要求使用礼堂的起始时间si和结束时间fi, 且有si<fi,。若区间(si,fi,)和(sj,fj,)不相交,则称活动i与活动j是相容的。

现在给定n个活动的开始时间和结束时间,请设计一个活动安排方案,使得安排的相容活动数目最多。

表1 活动时间表

1

2

3

4

5

6

7

8

10

11

12

1

2

0

5

3

5

6

8

2

12

15

3

4

5

7

8

9

10

11

13

14

18

#include <stdio.h>  
#include <stdlib.h>  
  
// 定义活动结构体,包含活动的索引、开始时间和结束时间  
struct Activity {  
    int index;     // 活动的索引或编号  
    int start;     // 活动的开始时间  
    int end;       // 活动的结束时间  
};  
  
// 比较函数,用于qsort,根据活动的结束时间进行排序  
// 返回值小于0表示a小于b,大于0表示a大于b,等于0表示a等于b  
int compare(const void *a, const void *b) {  
    struct Activity *activityA = (struct Activity *)a; // 将void指针转换为Activity指针  
    struct Activity *activityB = (struct Activity *)b; // 将void指针转换为Activity指针  
    return (activityA->end - activityB->end); // 返回两个活动结束时间的差值  
}  
  
int main() {  
    int n = 12; // 活动的总数  
      
    // 初始化活动数组  
    struct Activity activities[] = {  
        {1, 1, 3},  
        {2, 12, 14},  
        {3, 0, 5},  
        {4, 5, 7},  
        {5, 6, 10},  
        {6, 3, 8},  
        {7, 8, 12},  
        {8, 5, 9},  
        {9, 8, 11},  
        {10, 2, 13},  
        {11, 2, 4},  
        {12, 15, 18}  
    };  
      
    // 使用qsort函数对活动数组进行排序,根据活动的结束时间  
    qsort(activities, n, sizeof(struct Activity), compare);  
      
    // 初始化计数器,用于记录被安排的活动数量  
    int counter = 1; // 至少可以安排一个活动  
      
    // 初始化最后一个已安排活动的结束时间  
    int last_end_time = activities[0].end; // 第一个活动的结束时间  
      
    // 打印第一个被安排的活动  
    printf("第%d个活动被安排: %d开始, %d结束.\n", activities[0].index, activities[0].start, activities[0].end);  
      
    // 遍历剩余的活动,尝试安排它们  
    for (int i = 1; i < n; i++) {  
        // 如果当前活动的开始时间不小于上一个已安排活动的结束时间,则可以安排  
        if (activities[i].start >= last_end_time) {  
            counter++; // 增加计数器  
            printf("第%d个活动被安排: %d开始, %d结束.\n", activities[i].index, activities[i].start, activities[i].end);  
              
            // 更新最后一个已安排活动的结束时间  
            last_end_time = activities[i].end;  
        }  
    }  
      
    // 打印总计被安排的活动数量  
    printf("总计%d个活动被安排\n", counter);  
      
    return 0;  
}

运行结果:

9. 设有n个独立的作业{1,2…,n},由m台相同的机器进行加工处理。作业i所需时间为Ti。约定任何作业可以在任何一台机器上加工处理,但未完工前不允许中断处理,任何作业不能拆分成更小的子作业。要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。输入第一行输入n和m;第二行输入n个整数,分别表示n个作业做需要的时间,输出结果为一个整数,表示完成任务的最短时间。

#include <stdio.h>
#include <stdlib.h>
 
// 比较函数,用于排序作业
int compare(const void *a, const void *b) {
    return (*(int*)b - *(int*)a);
}
 
// 计算完成任务的最短时间
int shortestCompletionTime(int n, int m, int jobs[]) {
    // 按处理时间从大到小排序作业
    qsort(jobs, n, sizeof(int), compare);
 
    // 初始化每台机器的当前总处理时间为0
    int machines[m];
    for (int i = 0; i < m; i++) {
        machines[i] = 0;
    }
 
    // 将作业分配给机器
    for (int i = 0; i < n; i++) {
        // 找到当前处理时间最短的机器
        int minIndex = 0;
        for (int j = 1; j < m; j++) {
            if (machines[j] < machines[minIndex]) {
                minIndex = j;
            }
        }
        // 分配作业给当前处理时间最短的机器,并更新其总处理时间
        machines[minIndex] += jobs[i];
    }
 
    // 找到所有机器中总处理时间最长的时间
    int maxTime = machines[0];
    for (int i = 1; i < m; i++) {
        if (machines[i] > maxTime) {
            maxTime = machines[i];
        }
    }
 
    return maxTime;
}
 
int main() {
    int n, m;
    scanf("%d %d", &n, &m);
 
    int jobs[n];
    for (int i = 0; i < n; i++) {
        scanf("%d", &jobs[i]);
    }
 
    // 计算并输出完成任务的最短时间
    int shortestTime = shortestCompletionTime(n, m, jobs);
    printf("%d", shortestTime);
    return 0;
}

运行结果:

10. n个孩子站成一排。输入一个整数数组 ratings 表示每个孩子的评分。你需要按照以下要求,给这些孩子分发苹果:每个孩子至少分配到1个苹果。相邻两个孩子评分更高的孩子会获得更多的苹果。请你给每个孩子分发苹果,计算并返回需要准备的最少苹果数目。

#include <stdio.h>
 
int minApples(int ratings[], int n) {
    if (n <= 0) return 0;
    int apples[n];
    for (int i = 0; i < n; ++i) apples[i] = 1; // 每个孩子至少分配一个苹果
    
    // 从左向右扫描,保证右边评分高的孩子拿到的苹果比左边多
    for (int i = 1; i < n; ++i) {
        if (ratings[i] > ratings[i - 1]) {
            apples[i] = apples[i - 1] + 1;
        }
    }
    
    // 从右向左扫描,保证左边评分高的孩子拿到的苹果比右边多
    for (int i = n - 2; i >= 0; --i) {
        if (ratings[i] > ratings[i + 1] && apples[i] <= apples[i + 1]) {
            apples[i] = apples[i + 1] + 1;
        }
    }
    
    int totalApples = 0;
    for (int i = 0; i < n; ++i) {
        totalApples += apples[i];
    }
    
    return totalApples;
}
 
int main() {
    int n;
    scanf("%d", &n);
    int ratings[n];
    for (int i = 0; i < n; ++i) {
        scanf("%d", &ratings[i]);
    }
    
    int minTotalApples = minApples(ratings, n);
    printf("%d", minTotalApples);
    
    return 0;
}

运行结果:

 结语

宝剑锋从磨砺出

梅花香自苦寒来

!!!

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

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

相关文章

【电路笔记】-偏置晶体管

偏置晶体管 文章目录 偏置晶体管1、概述2、共发射极晶体管偏置3、集极反馈偏置4、双反馈晶体管偏置5、发射极反馈配置6、分压器晶体管偏置晶体管偏置是将晶体管直流工作电压或电流条件设置为正确电平的过程,以便晶体管可以正确放大任何交流输入信号 1、概述 双极晶体管的稳态…

DBA | 炼气期,关系数据库及六大范式(NF)理论概述!

[ 知识是人生的灯塔&#xff0c;只有不断学习&#xff0c;才能照亮前行的道路 ] 前言简述 描述&#xff1a;上一章&#xff0c;我们简单了解了关系类型数据库&#xff0c;以及其相关产品&#xff0c;此章节我们由浅入深的学习一下什么是关系型数据库&#xff0c;不过在讲解关系…

中国县城建设统计年鉴(2015-2022年)

数据年限&#xff1a;2015-2022年&#xff0c;年鉴时间即为数据时间 数据格式&#xff1a;pdfexcel 数据内容&#xff1a; 共分12个部分&#xff0c; 包括县城市政公用设施水平&#xff08;人口密度/人均日生活用水量/供水普及率/燃气普及率/人均道路面积/建成区路网密度/污水处…

51单片机—电动车报警器

一. 入门 1.1 开发环境的安装 用什么写代码--语言是C&#xff0c;环境是keilKeil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统&#xff0c;与汇编相比&#xff0c;C语言在功能上、结构性、可读性、可维护性上有明显的优势&#xff0c;因而易学易用。…

江协科技51单片机学习- p37 红外遥控(外部中断)

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

提供三方API接口、调用第三方接口API接口、模拟API接口(三)使用AOP切面编程实现signature签名验证

接着第一篇文章 提供三方API接口、调用第三方接口API接口、模拟API接口&#xff08;一&#xff09;通过signature签名验证&#xff0c;避免参数恶意修改 我们来继续优化&#xff1a; /*** 模拟后端校验签名* param request* param data* return* throws UnsupportedEncodingEx…

[环境配置]C4D OC渲染器解决缺少cudnn_8_0_4Octance正版缺少cudnn_8_0_4_win文件解决方法

关于Octance正版缺少cudnn_8_0_4_win文件解决方法 可在此处https://download.csdn.net/download/FL1623863129/89605383进行下载 放到对应文件位置即可 在计算机图形学领域&#xff0c;Cinema 4D&#xff08;C4D&#xff09;作为一款顶尖的专业3D建模、动画与渲染软件&#x…

学生管理系统之数据模拟与数据显示

学生管理系统之数据模拟与数据显示 设计一个单例 模拟数据 显示数据

CSP-J 2022 填程题19.解析

19. &#xff08;枚举因数&#xff09;从小到大打印正整数 n 的所有正因数。 试补全枚举程序。 01 #include <bits/stdc.h> 02 using namespace std; 03 04 int main() { 05 int n; 06 cin >> n; 07 08 vector<int> fac; 09 fac.reserve((int)ce…

【算法】动态规划---多态dp问题

多态dp问题 一.[leetcode] (打家劫舍I) 17.16.按摩师二. [leetcode] 213. 打家劫舍 II三.[leetcode] 740. 删除并获得点数四.[leetcode] LCR 091. 粉刷房子五.[leetcode] 309. 买卖股票的最佳时机含冷冻期六.[leetcode] 714. 买卖股票的最佳时机含手续费七.[leetcode] 123. 买卖…

职场,要想逆袭,必须要“装”

普通人&#xff0c;没有家庭背景&#xff0c;没有社会资源&#xff0c;没有好学历&#xff0c;如何才能逆袭呢&#xff1f;有朝一日自己熬出头&#xff0c;又如何避免被别人针对呢&#xff1f; 最重要的就是要会“装”。 在社会上&#xff0c;只有资源多的人才能更好的生存&a…

opencv c++ python等比缩小或放大显示图片代码

c代码&#xff0c;其中scale_percent用来设置百分比&#xff0c;例如50 就是百分之五十&#xff0c;也就是一半的大小&#xff0c;当然也可以设置成200&#xff0c;相当于原来的2倍大小&#xff0c;注意图片路径换成实际路径。 #include <opencv2/opencv.hpp>int main()…

【Java零基础视频教程】综合练习题(一)——基础练习

文章目录 基础练习飞机票打印素数生成验证码复制数组评委打分数字加密抽奖双色球 基础练习 飞机票 机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。 ​ 按照如下规则计算机票价格&#xff1a;旺季&#xff08;5-10月&#xff09;头等舱9折&…

pxe安装部署

RHEL7为例&#xff1a; ifconfig查看ip 一.环境配置 1.配置软件仓库&#xff1a; mkdir /rhel7 mount /dev/cdrom /rhel7 echo mount /dev/cdrom /rhel74 >> /etc/rc.d/rc,local chmod x /etc/rc.d/rc.local 2.关闭火墙和selinux&#xff0c;下载…

【极速前进】20240706-24240714:用于Agent的树搜、理解LLM的语种困惑、事实知识抽取微调、Quiet-STaR

相关博客 【极速前进】20240706-24240714&#xff1a;用于Agent的树搜、理解LLM的语种困惑、事实知识抽取微调、Quiet-STaR 【极速前进】20240615-20240623&#xff1a;Zipper融合模态、VideoLLM视频理解、WebAgent可以自我改善、Nemotron-4、AnyGPT统一模态 【极速前进】20240…

Final Shell for Mac 虚拟机连接工具【简单易操作,轻松上手】【开发所需连接工具】

Mac分享吧 文章目录 效果一、下载软件二、安装软件三、运行测试安装完成&#xff01;&#xff01;&#xff01; 效果 一、下载软件 下载软件 链接&#xff1a;http://www.macfxb.cn 二、安装软件 三、运行测试 安装完成&#xff01;&#xff01;&#xff01;

Kubernets(k8s) 网络原理三:同主机内Pod相互访问

前两篇文章中我们介绍了pod怎么和宿主机通信以及pod怎么访问外网&#xff0c;这两种通信是理解pod间通信的基础。 关于pod间的相互访问&#xff0c;这里还需要细化一下。回想一下pod在k8s节点中的分布&#xff0c;两个pod可能分布在同一台宿主机上&#xff0c;也可能分布在不同…

可视化图表与页面源代码显示

可视化图表与页面源代码显示 页面效果&#xff1a; <!DOCTYPE html> <html lang"en" style"height: 100%"> <head><meta charset"utf-8"><title>饼状图</title><style>body {display: flex;height:…

基于51单片机的交通信号灯proteus仿真设计

1.功能简介 交通信号灯是一种经典应用电路&#xff0c;本设计基于51单片机&#xff0c;利用Proteus仿真软件构建了一个模拟交通信号灯系统。该系统能够模拟真实交通环境中的信号变化&#xff0c;包括红灯、黄灯和绿灯的切换&#xff0c;以及倒计时显示等功能&#xff0c;各种灯…

谷歌出品,一款免费的智能绘图工具

AutoDraw是由Google开发的一款基于网络的智能绘图工具&#xff0c;旨在通过人工智能技术帮助用户快速、简便地创建图画和图表。该工具于2017年4月11日由谷歌创意实验室推出&#xff0c;并迅速获得了广泛关注。 AutoDraw的核心功能是利用机器学习算法识别用户的草图或涂鸦&…