C++贪心算法一(练习题)

贪心算法(一)-训练1-1

区间覆盖问题(最少点覆盖)

【描述】给定多个区间,用最少的点覆盖所有区间。

【输入描述】区间数n,随后2n个整数(左端点 右端点,n组)

【输出描述】最少需要的点数

【样例输入】

3

1 3

2 5

4 6

【样例输出】

2

cpp 复制代码
#include <iostream>
#include <algorithm>
using namespace std;

struct Interval 
{
    int left, right;
};

bool compare(Interval a, Interval b) 
{
    return a.right < b.right; // 按右端点排序
}

int minPoints(Interval arr[], int n)
{
    sort(arr, arr + n, compare);
    int points = 0, lastPoint = -1;
    for (int i = 0; i < n; i++) 
    {
        if (arr[i].left > lastPoint) 
        {
            points++;
            lastPoint = arr[i].right; // 选当前区间的右端点
        }
    }
    return points;
}

int main()
{
    int n;
    cin >> n;
    Interval arr[n];
    for (int i = 0; i < n; i++)
    {
        cin >> arr[i].left >> arr[i].right;
    }
    cout << minPoints(arr, n) << endl;
    return 0;
}

/*
【输入用例2】
3
1 3
2 5
4 6
【输出用例2】
2
【输入用例3】
3
0 0
0 1
1 2
【输出用例3】
2
【输入用例4】
5
1 2
3 4
5 6
7 8
9 10
【输出用例4】
5
【输入用例5】
4
1 5
2 5
3 5
4 5
【输出用例5】
1
【输入用例6】
1
100 200
【输出用例6】
1
*/

贪心算法(一)-训练1-2

均分纸牌问题(最少移动次数)

【描述】n堆纸牌,每次移动随意张到相邻堆,求使各堆数量相同的最少移动次数。

【输入描述】纸牌数n,随后n个整数(各堆数量)

【输出描述】最少移动次数

【样例输入】

3

3 1 2

【样例输出】

1

cpp 复制代码
#include <iostream>
using namespace std;

int main() 
{
    int n;
    cin >> n;
    int a[n];
    int sum = 0;
    
    // 输入并计算总和
    for (int i = 0; i < n; i++) 
    {
        cin >> a[i];
        sum += a[i];
    }
    
    int avg = sum / n;  // 计算平均值
    int moves = 0;      // 移动次数
    int prefix = 0;     // 前缀和
    
    // 遍历计算移动次数
    for (int i = 0; i < n; i++) 
    {
        prefix += a[i] - avg;  // 计算累计差值
        if (i != n-1 && prefix != 0) 
        {
            moves++;  // 每次传递差值产生一次移动
        }
    }
    cout << moves << endl;
    return 0;
}

/*
【输入用例2】
3
3 1 2
【输出用例2】
1
【输入用例3】
5
6 6 6 6 6
【输出用例3】
0
【输入用例4】
2
6 8
【输出用例4】
1
【输入用例5】
4
6 8 8 6
【输出用例5】
2
【输入用例6】
6
6 12 18 24 30 36 42
【输出用例6】
5
*/

贪心算法(一)-训练1-3

汽水瓶兑换问题

【描述】每3个空瓶换1瓶汽水,n个空瓶最多能喝多少瓶?

【输入描述】空瓶数n

【输出描述】最多能喝的汽水数

【样例输入】

21

【样例输出】

10

cpp 复制代码
#include <iostream>
using namespace std;

int maxSoda(int n) 
{
    int total = 0, empty = n;
    while (empty >= 3) 
    {
        int newSoda = empty / 3;
        total += newSoda;
        empty = empty % 3 + newSoda; // 剩余空瓶 + 新喝的空瓶
    }
    return total;
}

int main()
{
    int n;
    cin >> n;
    cout << maxSoda(n) << endl;
    return 0;
}

/*
【输入用例2】
7
【输出用例2】
3
【输入用例3】
15
【输出用例3】
7
【输入用例4】
45
【输出用例4】
22
【输入用例5】
99
【输出用例5】
49
【输入用例6】
0
【输出用例6】
0
*/

贪心算法(一)-训练2-1

纪念品分组

元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品,并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。

你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。

【输入】共 n+2行:(0<=n<=50)

第一行包括一个整数 w,为每组纪念品价格之和的上限。

第二行为一个整数 n,表示购来的纪念品的总件数。

第 3~n+2行每行包含一个正整数 Pi表示所对应纪念品的价格。

【输出】

一个整数,即最少的分组数目。

【输入样例】

100

9

90

20

20

30

50

60

70

80

90

【输出样例】

6

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 55;
int a[N], w, n, ans;

int main(){
    cin >> w >> n;
    for(int i = 1; i <= n; i++) 
		cin >> a[i];
		
    sort(a + 1, a + n + 1); //从小到大排序 

    int i = 1, j = n; // i左指针,j右指针 
    while(i <= j){
        if(a[i] + a[j] <= w){ //i,j之和不超w,两个组合打包
        	ans++, i++, j--;   
		}
		else
			ans++, j--; // 否则,(大的那个)j单独打包 
    }
    cout << ans;
    return 0;
}

/*
【输入用例2】
10 
4
1 
2 
3 
4
【输出用例2】
2
【输入用例3】
5 
3
1 
2 
5
【输出用例3】
2
【输入用例4】
4 
4
1 
1 
1 
1
【输出用例4】
2
【输入用例5】
3 
3
2 
2 
2
【输出用例5】
3
【输入用例6】
6 
5
1 
2 
3 
4 
5
【输出用例6】
3
*/

贪心算法(一)-训练2-2

最优装载问题(重量优先)

【描述】小王家有一条商务船,靠每天幸苦运货赚取学编程的费用,有一天他突发奇想:船的最大载重为C,有n个物品,重量分别为w0...n-1,我每次最多能装多少个物品呢?

【输入描述】C(载重),n(物品数),随后n个整数(物品重量)

【输出描述】最多能装的物品数量

【样例输入】

10

3

4 2 3

【样例输出】

3

cpp 复制代码
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    int C, n;
    cin >> C >> n;
    int w[100];
    for (int i = 0; i < n; i++) 
    {
        cin >> w[i];
    }
    sort(w, w + n); // 按重量升序排序
    
    int total = 0, count = 0;
    for (int i = 0; i < n; i++)
    {
        if (total + w[i] <= C) 
        {
            total += w[i];
            count++;
        } else break;
    }
    cout << count << endl;
    return 0;
}

/*
【输入用例2】
10
12
1 1 1 1 1 1 1 1 1 1 1 1
【输出用例2】
10
【输入用例3】
10
9
1 2 3 4 5 6 7 8 9 10
【输出用例3】
4
【输入用例4】
100
 6
12 56 48 32 11 2
【输出用例4】
4
【输入用例5】
200
10
12 23 54 1 2 56 3 96 62 70
【输出用例5】
7
【输入用例6】
500
13
10 20 30 40 50 60 70 80 90 100 110 120 130
【输出用例6】
9
*/
相关推荐
Coder-magician1 小时前
《代码随想录》刷题打卡day12:二叉树part02
数据结构·c++·算法
xinhuanjieyi2 小时前
Android 画板应用kotlin实现
android·开发语言·kotlin
threelab2 小时前
Three.js 几何图形变换 | 三维可视化 / AI 提示词
开发语言·前端·javascript·人工智能·3d·着色器
无限进步_2 小时前
Linux进程等待——wait、waitpid与僵尸进程
linux·运维·服务器·开发语言
野生技术架构师2 小时前
Java 23 种设计模式:从踩坑到精通 —— 开篇及系列介绍
java·开发语言·设计模式
Wang ruoxi2 小时前
Pygame 小游戏——数独
开发语言·python·pygame
人道领域2 小时前
【LeetCode刷题日记】90.子集Ⅱ--- 归纳题解
java·开发语言·leetcode
随意起个昵称2 小时前
线性dp-LIS题目5(导弹拦截,二分优化)
c++·算法·动态规划
ch.ju2 小时前
Java Programming Chapter 4——Characteristics of inheritance
java·开发语言