链接:登录—专业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]);
}
冒泡排序是一种简单的排序算法,它重复的便利需要排序的数列,一次比较两个元素,如果顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
冒泡排序算法的运作如下:
- 比较相邻的元素。如果第一个比第二个大,就交换它们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
由于它简单的性质,冒泡排序通常不适合对大量数据进行排序。