C语言算法——小辰的圣剑

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

小辰是异世界的勇士,小辰有一把耐久为 mmm 的圣剑。有一天,魔法师预言未来 nnn 天中的第 iii 天暗黑魔法师会召唤无数只血量为 aia_iai​ 的怪物袭击王国,且第 iii 天的怪物不会停留至第 i+1i+1i+1 天。

圣剑每对怪物造成一点伤害都会损耗一点耐久,当圣剑的耐久消耗完后就不能对怪物造成伤害了。当怪物的血量为 000 时,怪物就被小辰击杀了,如果第 iii 天成功击杀了至少一只怪物,小辰在国民中的声望就会增加 bib_ibi​,但是当小辰在国民中的声望超过 uuu 时,国王就会认为他的地位受到了威胁,从而囚禁小辰。

但是由于国民的记性很差,所以一旦有一天小辰没有出战,那么当天结束时小辰在国民中的声望就会降为 000。称小辰出战了,当且仅当当天小辰击杀了至少一只怪物。

但是小辰可以自主选择哪几天出战。小辰不想被囚禁自然不会想让自己在出战后的声望超过 uuu。

求小辰最多能连续出战多少天。

输入描述:

第一行三个整数 n (1≤n≤5000),m,u (1≤m,u≤5×1012)n\ (1\leq n\leq 5000),m,u\ (1\leq m,u \leq 5\times 10^{12})n (1≤n≤5000),m,u (1≤m,u≤5×1012)。

第二行 nnn 个整数表示 ai (1≤ai≤109)a_i\ (1\leq a_i\leq 10^9)ai​ (1≤ai​≤109)。

第三行 nnn 个整数表示 bi (−109≤bi≤109)b_i\ (-10^9 \leq b_i\leq 10^9)bi​ (−109≤bi​≤109)。

输出描述:

输出一行一个整数表示小辰最多能连续出战多少天。

示例

输入

4 7 10
2 3 4 5
6 7 8 9

输出

1

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
    long long n, durability, u;     //
    scanf("%lld%lld%lld", &n, &durability, &u);

    //动态分配内存
    long long* a = (long long *)malloc(n * sizeof(long long));
    long long* b = (long long *)malloc(n * sizeof(long long));
    long long* day = (long long*)malloc(n * sizeof(long long));     //day是连续出战天数的数组

    int i, j;
    long long  prestige, max_days, durability_0 = durability;     //durability_0是圣剑的初始耐久度
    for (i = 0; i < n; i++)
        scanf("%lld", &a[i]);
    for (i = 0; i < n; i++)
        scanf("%lld", &b[i]);
    for (i = 0; i < n; i++) {
        durability = durability_0;   //用来在每一轮新的尝试中重置圣剑的耐久度
        max_days = 0;   //max_days 用于计数在每一轮尝试中,小明能连续出战的天数
        j = i;      //将j设置为当前的起始天数i
        prestige = 0;   //prestige是小辰的当前声望
        while (prestige <= u && j < n) {
            if (durability - a[j] < 0)break;
            if (durability - a[j] >= 0) {
                prestige += b[j];
                durability = durability - a[j];
                j++;
                if (prestige <= u) max_days++;
            }

        }
        day[i] = max_days;
    }

    //冒泡循环,使得day数组中的元素从大到小排列
    int temp;
    for (i = 0; i < n - 1; i++) {
        for (j = 0; j < n - 1; j++) {
            if (day[j] < day[j + 1]) {
                temp = day[j];
                day[j] = day[j + 1];
                day[j + 1] = temp;
            }
        }
    }
    printf("%lld", day[0]);
}

VS编译器中

  • 注释整段代码:Ctrl+K,Ctrl+C
  • 取消注释整段代码:Ctrl+K,Ctrl+U

C语言打印数组中的元素:

需要使用循环来遍历数组,不能像python那样直接打印。

动态内存分配

我想定义一个数组 list[n] ,而 n 是一个变量,它的值从屏幕中输入。这时需要使用动态内存分配来创建一个大小为 n 的数组。在C语言中,可使用 malloc 函数来实现动态内存分配。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int n;
    scanf("%d",&n);
    int *list_a=(int *)malloc(n * sizeof(int));

    if (list_a == NULL)
        {
            printf("Memory allocation failed\n");
            return 1;
        }

    for (int i = 0;i<n;i++)
    {
        scanf("%d",&list_a[i]);
    }

    //其他操作

    free(list_a);

    return 0;
}

#include<stdio.h> 和 #include<stdlib.h>

包含两个预处理指令,用于引入标准输入输出库(stdio.h)和动态内存分配相关函数库(stdlib.h)

int *list_a = (int *)malloc(n * sizeof(int))

使用 malloc 动态分配内存,创建了整数指针 list_a ,用于存储大小为n的整数数组。这里使用了 sizeof(int) 来确保整数的大小分配足够的内存空间。

malloc 函数

malloc接受一个参数size,表示需要分配的字节数。

它返回一个 void* 类型的指针,指向新分配的内存块的起始地址。

malloc 是C语言中的一个函数,用于动态分配内存。它接受一个参数,即要分配的字节数,返回一个指向新分配内存空间的指针。

(int *)是一种类型转换,将malloc返回的通用指针(void *)转换为指向整数的指针(int *)。

list_a是一个指向整数的指针,它被赋值为malloc返回的分配的内存块的起始地址。

整句代码的作用是:使用malloc函数动态分配了一个能够容纳 n 个整数的内存块,并将其起始地址存储在指向整数的指针 list_a 中。这样,就可以通过 list_a 来访问这块动态分配的内存,以存储和检索整数值。

提醒:使用完动态分配的内存后,应该使用 free函数 释放这些内存,以免发生内存泄漏。

动态分布内存:

静态内存是在程序编译时分配的,而动态内存是在程序运行时分配的。动态内存分配允许你根据程序的运行情况动态的请求和释放内存。

起始地址:

“起始地址”指的是内存块的第一个字节的地址,通过指向它的指针,可以访问整个内存块的内容。在C语言中,内存是一块连续的字节序列,每个字节都有唯一的地址。

示例:使用malloc分配了一个包含5个整数的内存块:

int* list_a = (int*)malloc(5 * sizeof(int))

在这个例子中,list_a存储了动态分配内存块的第一个整数的地址,即内存块的起始地址。通过list_a,你可以访问整个内存块,因为它提供了对第一个元素及其后续元素的指针。

内存块的起始地址对于指针操作和访问数组元素至关重要。通过在起始地址上进行指针算术运算,可以访问内存块中的其它元素。例如,list_a+1将指向内存块中的第二个整数,list_a+2将指向第三个整数,以此类推。

void指针:

void*是一种通用指针类型,可以指向任何类型的数据。这意味着malloc返回的指针最初没有指定它指向的数据类型。因此,在实际使用中,通常需要将void*转换为适当的指针类型,以便正确使用内存。

int* list_a=(int* )malloc(n * sizeof(int));

这里malloc返回的void*被转换为int*类型,以便正确引用整数类型的数据。

使用分配的内存:

一旦分配了内存,你可以通过使用指针进行访问和操作。list_a就是一个指向动态分配内存块的指针,可以通过list_a来存储和检索整数值。

数组操作:

在C中,数组名本质上是指向数组首元素的指针。通过将list_a声明为指针,可以通过使用类似数组的语法来访问和操作分配的内存块。

总体而言,malloc返回的指针是一个地址,指向动态分配的内存块的起始位置,使得程序能够在运行时动态管理内存。

指针:

在C语言中,指针是一种特殊的变量类型,用于存储其他变量的内存地址。通过指针,可以访问和操作存储在改地址上的数据。

冒泡排序

    //冒泡循环,使得day数组中的元素从大到小排列
    int temp;
    for (i = 0; i < n - 1; i++) {
        for (j = 0; j < n - 1; j++) {
            if (day[j] < day[j + 1]) {
                temp = day[j];
                day[j] = day[j + 1];
                day[j + 1] = temp;
            }
        }
    }
    printf("%lld", day[0]);
}

冒泡排序是一种简单的排序算法,它重复的便利需要排序的数列,一次比较两个元素,如果顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

冒泡排序算法的运作如下:

  1.  比较相邻的元素。如果第一个比第二个大,就交换它们两个。
  2.  对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3.  针对所有的元素重复以上的步骤,除了最后一个。
  4.  持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

由于它简单的性质,冒泡排序通常不适合对大量数据进行排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值