贪心算法(二)-训练1-1
字典序最小的字符串(删除k个字符)
【描述】给定字符串s和整数k,删除k个字符后得到字典序最小的字符串。
【输入描述】字符串s,整数k(保证k < s.length())
【输出描述】删除后的最小字典序字符串。
【样例输入】
helloword
3
【样例输出】
ellood
cpp
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main() {
string s; // 输入的数字字符串
int k; // 需要删除的字符个数
cin >> s >> k;
string result;
// 遍历原字符串中的每一个字符
for (char current_char : s) {
// 贪心策略:尽可能让前面的数字更小
while (!result.empty() && k > 0 && result.back() > current_char) {
result.pop_back(); // 删除末尾较大的字符
k--; // 剩余删除次数减1
}
result.push_back(current_char); // 将当前字符加入结果
}
// 处理可能剩余的删除次数(例如所有字符递增时,需要删除末尾的k个字符)
if (k > 0) {
result.resize(result.size() - k);
}
// 去除前导零(例如结果为"0200"时,应输出"200")
size_t first_non_zero = result.find_first_not_of('0');
if (first_non_zero == string::npos) { // 所有字符都是0的情况(如"000")
cout << "0";
} else { // 存在非零字符,输出从第一个非零字符开始的子串
cout << result.substr(first_non_zero);
}
return 0;
}
/*
【输入用例2】
goodmorning
5
【输出用例2】
dmning
【输入用例3】
mynameiszhangsan
9
【输出用例3】
aangsan
【输入用例4】
whatisyuoename
4
【输出用例4】
aisuoename
【输入用例5】
stringandlength
7
【输出用例5】
adlength
【输入用例6】
includeiostreamalgorithmstring
15
【输出用例6】
aagorithmstring
*/
贪心算法(二)-训练1-2
图书排序(价格+作者)
【描述】输入n本书的价格和作者,按价格升序、价格相同按作者字典序升序排列。
【输入描述】一个数n,随后n行每行一个整数(价格)和一个字符串(作者)。
【输出描述】排序后的图书列表。
【样例输入】
3
200 李四
100 张三
150 王五
【样例输出】
100 张三
150 王五
200 李四
cpp
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
struct Book {
int price; // 书的价格
string author; // 书的作者
};
bool compare(Book a, Book b) {
// 比较价格
if (a.price != b.price) {
return a.price < b.price; // 按价格升序排列(价格低的在前)
}
// 价格相同,比较作者名
return a.author < b.author; // 按作者名的字典序升序排列(字母顺序靠前的在前)
}
int main() {
int n;
cin >> n; // 输入书的数量
// 创建一个Book类型的数组,最多可以存储100本书
Book books[100];
// 循环读取每本书的价格和作者信息
for (int i = 0; i < n; i++)
{
cin >> books[i].price >> books[i].author;
}
sort(books, books + n, compare);
// 循环输出排序后的书籍信息
for (int i = 0; i < n; i++)
{
cout << books[i].price << " " << books[i].author << endl;
}
return 0;
}
/*
【输入用例2】
2
200 王五
200 李四
【输出用例2】
200 李四
200 王五
【输入用例3】
2
150 张三
150 张三
【输出用例3】
150 张三
150 张三
【输入用例4】
1
300 赵六
【输出用例4】
300 赵六
【输入用例5】
3
300 张三
200 李四
100 王五
【输出用例5】
100 王五
200 李四
300 张三
【输入用例6】
2
120 Bob
120 Alice
【输出用例6】
120 Alice
120 Bob
*/
贪心算法(二)-训练1-3
删减字符使递增
【描述】输入一个字符串(小写或大写字母),按照从左到有的顺序,当后一个字符要大于前一个字符时保留,否则删除后一个字母字符,最后使字符串严格递增。
【输入描述】字符串s
【输出描述】处理后的字符串(严格递增)。
【样例输入】
helloword
【样例输出】
hlow
cpp
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string s;
cin >> s;
string res;
char last = '0'; // 初始为最小字符
for (char c : s)
{
if (c > last)
{ // 只保留比上一个大的字符
res.push_back(c);
last = c;
}
}
cout << res << endl;
return 0;
}
/*
【输入用例2】
ABCdef
【输出用例2】
ABCdef
【输入用例3】
include
【输出用例3】
inu
【输入用例4】
iostream
【输出用例4】
iost
【输入用例5】
algorithm
【输出用例5】
alort
【输入用例6】
usingnamespace
【输出用例6】
u
*/
贪心算法(二)-训练2-1
分发饼干
【描述】假设你是一位很棒的家长,想要给你的n个孩子们分发m块小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj 。
如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。
你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
【输入描述】 第一行一个正整数n表示孩子数量(n<=10),后面一行 n个正整数表示每个孩子的胃口值g。
第三行一个正整数 m表示饼干的数量(m<=20), 后面一行 m个正整数表示每块饼干的尺寸s。
【输出描述】 最多能满足多少孩子。
【输入样例1】
3
1 2 3
2
1 1
【输出样例1】
1
【输入样例2】
2
1 2
3
2 1 3
【输出样例2】
2
【思路】 典型贪心策略,尽可能的用小饼干喂饱胃口小的孩子。
首先将两个数组升序排序;
顺序遍历两个数组:
1、如果当前饼干喂不饱当前的小孩,那么后面所有的小孩肯定也喂不饱,
所以直接查看下一个饼干能否喂饱当前的小孩,直到一个饼干可以喂饱当前的小孩
统计结果加1;
2、继续给下一个孩子找饼干。
cpp
#include<iostream>
#include<algorithm>
using namespace std;
int g[11];
int s[21];
int main(){
int n,m;
cin >> n;
for(int i=0;i<n;i++)
cin >> g[i];
cin >> m;
for(int i=0;i<m;i++)
cin >> s[i];
// 首先将两个数组从小到大排序
sort(g,g+n);
sort(s,s+m);
int i = 0, j = 0, ans = 0; // i作为g指针,j为s指针
while(i < n && j < m){
if(s[j] >= g[i]){
// 满足了一个小孩,g指针后移1,ans加1
i++;
ans++;
}
// 不管当前饼干是否可以满足此小孩,s指针都向后移1
j++;
}
cout << ans;
return 0;
}
/*
【输入用例2】
3
1 2 3
3
1 1 2
【输出用例2】
2
【输入用例3】
3
1 2 3
3
3 4 5
【输出用例3】
3
【输入用例4】
3
5 6 7
3
1 2 3
【输出用例4】
0
【输入用例5】
4
2 2 2 2
4
2 2 2 2
【输出用例5】
4
【输入用例6】
4
1 1 2 2
4
1 1 2 2
【输出用例6】
4
*/
贪心算法(二)-训练2-2
分配任务给工人(最大时间最小化)
【描述】n个任务(处理时间已知),分配给m个工人(n <= m),求最终输出所有工人中总处理时间的最大值(即最忙工人的总耗时)。
【输入描述】n(任务数),m(工人数),随后n个整数(任务时间)
【输出描述】最忙工人的总耗时
【样例输入】
3 3
5 3 1
【样例输出】
5
cpp
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;//输入任务数量n和工人数量m。
int tasks[100];
for (int i = 0; i < n; i++)
{
cin >> tasks[i];
}
sort(tasks, tasks + n, greater<int>()); // 降序排列
int workers[100] = {0};
for (int i = 0; i < n; i++)
{
workers[i % m] += tasks[i]; // 轮流分配给工人
}
int maxTime = 0;
for (int i = 0; i < m; i++) //遍历所有工人,找到总耗时最大的值。
{
if (workers[i] > maxTime)
maxTime = workers[i];
}
cout << maxTime << endl;
return 0;
}
/*
【输入用例2】
2 3
4 2
【输出用例2】
4
【输入用例3】
5 2
10 8 6 4 2
【输出用例3】
18
【输入用例4】
4 2
5 5 5 5
【输出用例4】
10
【输入用例5】
3 1
3 1 2
【输出用例5】
6
【输入用例6】
4 2
7 6 5 4
【输出用例6】
12
*/
贪心算法(二)-训练2-3
股票买卖最佳时机
【描述】给定每天股价,求一次交易(买入后卖出)能获得的最大利润。
【输入描述】n(天数),随后n个整数(股价)。
【输出描述】最大利润(无法盈利则输出0)。
【样例输入】
6
7 1 5 3 6 4
【样例输出】
5
cpp
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n; // 输入股票价格的天数
int prices[100]; // 存储每天的股票价格
for (int i = 0; i < n; i++) {
cin >> prices[i]; // 输入每天的价格
}
// minPrice:记录遍历到当前时,遇到的最低价格(初始为第一天的价格)
// maxProfit:记录当前能获得的最大利润(初始为0,即不交易的情况)
int minPrice = prices[0], maxProfit = 0;
// 从第二天开始遍历(因为第一天只能买入,无法卖出)
for (int i = 1; i < n; i++) {
if (prices[i] < minPrice)
{
// 如果今天的价格比之前记录的最低价格还低,更新最低价格为今天的价格
minPrice = prices[i];
}
else
{
// 如果今天的价格不低于最低价格,计算今天卖出的利润(今天价格 - 最低买入价),并更新最大利润(取当前最大利润和新利润中的较大值)
maxProfit = max(maxProfit, prices[i] - minPrice);
}
}
cout << maxProfit << endl; // 输出最大利润
return 0;
}
/*
【输入用例2】
4
1 2 3 4
【输出用例2】
3
【输入用例3】
3
5 4 3
【输出用例3】
0
【输入用例4】
5
3 8 1 2 9
【输出用例4】
8
【输入用例5】
5
2 2 1 1 3
【输出用例5】
2
【输入用例6】
5
5 4 3 2 10
【输出用例6】
8
*/