一列火车从第 0 站开到第 n n n 站,有 m m m 个座位, x x x 名乘客,每个乘客给定上下车站点 a i a_i ai 和 b i b_i bi。要求找出一组乘客安排,使得任一时刻乘客总数不超过 m m m,且所有乘客的乘坐站数总和最大化。
输入:
m n x
a1 b1
a2 b2
...
ax bx
输出:
#include
#include // 包含字符串处理函数,如memset
// 定义一个结构体表示乘客的行程信息
typedef struct passager {
int start; // 乘客上车的站点
int end; // 乘客下车的站点
} passager;
// 定义一个简单的最大值函数
int max(int a, int b) {
return (a > b) ? a : b; // 返回a和b中的较大值
}
// 定义最大座位数、最大站点数和最大乘客数
#define max_seat 10
#define max_station 20
#define max_people 10
int main() {
// 定义一些变量
int m = 10; // 最大座位数
int n = 20; // 最大站点数
int x = 9; // 最大乘客数
int valid = 1; // 用于标记当前组合是否有效
int ans = 0; // 当前组合的总行程长度
int result = 0; // 最终结果,即最大有效行程长度
// 修改变量值,用于测试
m = 2; // 修改最大座位数为2
n = 11; // 修改最大站点数为11
x = 4; // 修改最大乘客数为4
// 定义一个乘客数组,最多支持max_people个乘客
passager p[max_people];
// 初始化乘客的行程信息
p[0].start = 0; p[0].end = 1; // 第一个乘客从站点0到站点1
p[1].start = 1; p[1].end = 9; // 第二个乘客从站点1到站点9
p[2].start = 0; p[2].end = 10; // 第三个乘客从站点0到站点10
p[3].start = 3; p[3].end = 8; // 第四个乘客从站点3到站点8
// 定义一个数组,用于记录每个站点的乘客数量
int count[max_station] = {0}; // 初始化所有站点的乘客数量为0
// 遍历所有可能的乘客组合
for (int i = 0; i < (1 << x); i++) { // 1<
ans = 0; // 重置当前组合的总行程长度
memset(count, 0, sizeof(count)); // 把整个数组的所有字节设置为0,即重置每个站点的乘客数量
valid = 1; // 假设当前组合是有效的
// 遍历每个乘客
for (int j = 0; j < x; j++) {
// 检查当前乘客是否在当前组合中
if ((i >> j) & 1) { // 如果第j位为1,表示乘客j在当前组合中
// 遍历该乘客的行程范围
for (int k = p[j].start; k < p[j].end; k++) {
count[k]++; // 该站点的乘客数量加1
if (count[k] > m) { // 如果某个站点的乘客数量超过最大座位数
valid = 0; // 标记当前组合无效
break; // 退出内层循环
}
}
if (valid == 0) {
break; // 如果当前组合无效,退出外层循环
} else {
ans += p[j].end - p[j].start; // 累加当前乘客的行程长度
}
}
}
// 如果当前组合有效,更新最大行程长度
if (valid) {
result = max(result, ans); // 更新最大行程长度
}
printf("%d\n", result); // 打印当前的最大行程长度
}
// 打印最终结果
printf("%d", result);
return result; // 返回最终结果
}
头文件:
#include
:包含标准输入输出库,用于printf
等函数。#include
:包含字符串处理函数,如memset
,用于初始化数组。结构体定义:
typedef struct passager
:定义了一个结构体passager
,包含两个成员变量start
和end
,分别表示乘客的上车和下车站点。最大值函数:
int max(int a, int b)
:定义了一个简单的函数,返回两个整数中的较大值。宏定义:
#define max_seat 10
:定义最大座位数。#define max_station 20
:定义最大站点数。#define max_people 10
:定义最大乘客数。变量定义:
int m
:最大座位数。int n
:最大站点数。int x
:乘客数量。int valid
:标记当前乘客组合是否有效。int ans
:当前组合的总行程长度。int result
:最终结果,即所有有效组合中的最大行程长度。乘客行程初始化:
p
,并初始化了4个乘客的行程信息。站点乘客数量数组:
count
,用于记录每个站点的乘客数量,初始化为0。遍历所有乘客组合:
for (int i = 0; i < (1 << x); i++)
,通过位运算生成所有可能的乘客组合。1 << x
表示2的x次方,即所有乘客的组合数。检查每个组合的有效性:
m
。如果超过,则标记该组合无效。更新最大行程长度:
result
。输出结果:
输入:
2 10 3
0 5
2 8
5 10
输出:
15
说明:第 1、2、3 位乘客都能安排,每个人乘坐 5、6、5 站,加起来为 16,但如果超了座位限制,就只能选两人,最优组合就是乘坐站数和为 15。
可以考虑贪心或动态规划的方式进一步优化,但由于本题规模较小,暴力+剪枝方式是最直接有效的方法。
for (int i = 0; i < (1 << x); ++i)
这是用来遍历2x 次,1<
这行代码:
int count[n]
:定义了一个长度为 n
的整型数组,n
必须是一个已定义的整数常量(在C中,不能是变量,除非使用C99变长数组或在GCC扩展中允许)。{0}
:这是一种聚合初始化,只给出了第一个元素的初始值,其他未显式初始化的元素会自动初始化为 0。const int n = 5;
int count[n] = {0}; // 等价于 int count[n] = {0, 0, 0, 0, 0};
C语言如何清零数组
memset(count, 0, sizeof(count)); // 把整个数组的所有字节设置为 0
华为刷题第一题,直接暴力穷举。确实挺绕思路的。但是一点点进步。拿到一百五十分。