用c语言贪心法实现下面题目并给出详细注释
时间: 2024-02-20 15:56:43 浏览: 76
c语言贪心算法
很高兴为您解答这道题目!以下是用C语言实现的贪心算法代码:
题目描述:
有n个区间,区间i表示为[L[i],R[i]],现在需要从中选出尽可能多的区间,使得它们之间互不重叠。请你找出这样的区间组合中,包含区间数最多的一种,并输出包含的区间数。
输入格式:
第一行包含一个整数n,表示区间数。
接下来n行,每行包含两个整数L[i]和R[i],表示区间的左端点和右端点。
输出格式:
共一行,包含一个整数,表示最多包含多少个区间。
样例输入:
5
1 2
2 3
3 4
1 3
4 5
样例输出:
3
代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int left;
int right;
} Interval;
int cmp(const void* a, const void* b) {
return ((Interval*)a)->right - ((Interval*)b)->right;
}
int main() {
int n;
scanf("%d", &n);
Interval intervals[n];
for (int i = 0; i < n; i++) {
scanf("%d %d", &intervals[i].left, &intervals[i].right);
}
// 按照右端点从小到大排序
qsort(intervals, n, sizeof(Interval), cmp);
int count = 0;
int end = -1;
for (int i = 0; i < n; i++) {
if (intervals[i].left >= end) {
count++;
end = intervals[i].right;
}
}
printf("%d\n", count);
return 0;
}
```
代码注释:
1. 定义结构体Interval,表示区间的左右端点。
```c
typedef struct {
int left;
int right;
} Interval;
```
2. 定义比较函数cmp,用于按照右端点从小到大排序。
```c
int cmp(const void* a, const void* b) {
return ((Interval*)a)->right - ((Interval*)b)->right;
}
```
比较函数需要返回一个整数值,如果返回小于0的值,则表示a在前,b在后;如果返回大于0的值,则表示b在前,a在后;如果返回0,则表示a和b相等。
在本题中,比较函数按照右端点从小到大排序,因此如果a的右端点小于b的右端点,则a在前,b在后。
3. 读入区间的左右端点。
```c
Interval intervals[n];
for (int i = 0; i < n; i++) {
scanf("%d %d", &intervals[i].left, &intervals[i].right);
}
```
4. 按照右端点从小到大排序。
```c
qsort(intervals, n, sizeof(Interval), cmp);
```
使用qsort函数进行排序,需要传入以下四个参数:
- 待排序的数组的地址。
- 数组中元素的个数。
- 每个元素的大小。
- 比较函数的地址。
5. 使用贪心算法求解最多包含多少个区间。
```c
int count = 0;
int end = -1;
for (int i = 0; i < n; i++) {
if (intervals[i].left >= end) {
count++;
end = intervals[i].right;
}
}
```
首先初始化count为0,表示当前包含的区间数为0。
然后定义变量end为-1,表示当前的右端点为-1。
遍历所有的区间,如果当前区间的左端点大于等于end,则说明该区间可以被选中,此时将count加1,并将end更新为该区间的右端点。
最后输出count,即为最多包含的区间数。
注意,本题中的区间是左闭右闭区间,因此如果两个区间的左端点相等,右端点靠前的区间应该排在前面。如果是左闭右开区间,则右端点靠后的区间应该排在前面。
阅读全文