贪心专题题目讲解

发布时间 2023-04-13 20:09:15作者: harper886

贪心专题题目讲解

学习网站:OI维基

B. Taxi

链接

B. Taxi

尽量选择3和1。并让2自己结合。如果 1 和 2 比较多,就让两个 1 和 2 组合,每四个 1 坐同一辆出租车。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
const int N = 100008;

int a[N];

signed main () {
	std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
	int n;
	int st[6] = {0};
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		st[a[i]]++;//每个小组有多少人
	}
	int ans = 0;
	//统计4个人的小组需要的车
	ans = ans + st[4];
	st[4] = 0;
	//统计2个人的小组需要的车
	ans = ans + st[2] / 2;
	st[2] = st[2] % 2; //剩下的2个人小组的人数
	//3个的小组和1个人的小组
	int mmin = min(st[3], st[1]);
	ans = ans + mmin; //有多少3人组和1人组配对
	st[3] = st[3] - mmin;
	st[1] = st[1] - mmin;

	if (st[3] > 0) { //如果存在3人组,只能单独坐一个车
		ans = ans + st[3];
		st[3] = 0;
	}

	if (st[2] > 0 && st[1] <= 2) {//如果存在2个人的小组,并且1人小组为小于两队
		st[2] = 0;
		st[1] = 0;
		ans++;//坐一辆车
	} else if (st[2] > 0 && st[1] > 2) {//如果存在2个人的小组,并且1人小组为大于两队,让一个车坐满
		st[2] = 0;
		st[1] = st[1] - 2;
		ans++;
	}
	ans = ans + (st[1] + 4 - 1) / 4;//最后让一人小队除以4向上取整
	cout << ans << '\n';








	return 0;
}

A. Li Hua and Maze

链接

A. Li Hua and Maze

1.我们可以发现如果点(x,y)位于正方形的四个角上把这个点围起来需要两次操作

2.如果点(x,y)在正方形的4条边上,需要3个操作将其其围起来

3.如果点(x,y)在其他地方需要4个操作将其围起来

我们求出两个坐标的最小值打印出来就可以

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
const int N = 100008;
int n, m;
int length(int x, int y) {
	if ((x == 1 && y == 1) || (x == 1 && y == m) || (x == n && y == 1) || (x == n && y == m)) { //4个点
		return 2;
	} else if (x == 1 || y == 1 || x == n || y == m) { //除去4个点的4条边

		return 3;
	} else {
		return 4;//其他情况
	}


}
void solve() {

	scanf("%lld %lld", &n, &m);
	int x1, y1, x2, y2;
	cin >> x1 >> y1 >> x2 >> y2;
	cout << min(length(x1, y1), length(x2, y2)) << '\n'; //求出x1,y1和x2,y2的最小值



}
signed main () {
	int t;
	cin >> t;
	while (t) {
		solve();
		t--;
	}


	return 0;
}

C. Two Teams Composing

链接

C. Two Teams Composing

1.先求出不同数字的数量()和相同数字最多的数量(mmax)

2.如果两者情况相同打印mmax-1

3.如果unique_num大于mmax打印mmax的数量

4.如果mmax>unique_num的数量打印unique_num的数量

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
const int N = 200005;

void solve() {
	int st[N] = {0};
	int n;
	cin >> n;
	int x;
	int unique_num = 0;
	int mmax = -1;
	for (int i = 0; i < n; i++) {
		cin >> x;
		if (st[x] == 0) {
			unique_num++;//获得不同数字的数量
		}
		st[x]++;
		mmax = max(st[x], mmax); //找出最大数字的数量
	}
	int ans = 0;
	if (unique_num == mmax) {//如果相同unique_num和mmax相同
		ans = mmax - 1;//丢弃一个数
	} else if (unique_num > mmax) {
		ans = mmax;//如果unique_num比较大,答案为mmax

	} else {
		ans = unique_num;//如果mmax比较大,答案为nuique_num;

	}
	cout << ans << '\n';//打印结果









}
signed main () {
	std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
	int t;
	cin >> t;
	while (t) {
		solve();
		t--;
	}


	return 0;
}

A. Dragons

链接

A. Dragons

1.先贪心的排序,将战斗力弱的龙排在前面,如果战斗力相同将打死得分高的龙排在前面

2.然后贪心的选择,选择的同时判断满不满足条件如果都满足条件,打印YES,只要有一次不满足条件打印NO

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
const int N = 1005;

struct point {
	int x, y;
};
struct point a[N];
//自定义排序方法,先让战斗力弱的龙在前面,如果两个龙战斗力相同,打死获取的力量多的龙在前面
bool cmp(struct point a, struct point b) {
	if (a.x != b.x) {
		return a.x < b.x;
	} else {
		return a.y > b.y;
	}


}
signed main () {
	std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
	int n, s;
	cin >> s >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i].x >> a[i].y;//读入数据
	}
	sort(a, a + n, cmp);//排序
	int flag = 1;//假设可以通关
	for (int i = 0; i < n; i++) {
		if (s > a[i].x) {//模拟打败第a[i]条龙
			s += a[i].y;
		} else {
			flag = 0;//只要有一个数据不符合就让flag=0;退出
			break;
		}

	}
	//打印结果
	if (flag == 1) {
		yes;
	} else {
		no;

	}



	return 0;
}

A. Chat room

链接

A. Chat room

1.构建目标串,然后和给定串进行逐一的对比,如果对比成功打印yes,否则打印no

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
const int N = 100008;


signed main () {
	std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
	string s;
	cin >> s;
	int flag = 0;
	string x = "hello";//目标串
	int index = 0;//目标串索引
	for (int i = 0; i < (int)s.size(); i++) {
		if (s[i] == x[index]) {//将目标串和给定的字符串进行一一比对
			index++;//比对成功让索引加1
			if (index == 5) {//如果目标串遍历到头了,这肯定是符合条件的
				flag = 1;//flag=1
				break;

			}
		}
	}
	//打印结果

	if (flag == 1) {
		yes;
	} else

	{
		no;

	}

	return 0;
}

A. Chewbaсca and Number

链接

A. Chewbaсca and Number

1.特判第一个字符,因为第一个字符不能为0,如果第一个字符为9这不操作,否则取t和9-t的较小值

2.后面的字符不需要特判,直接取t和9-t的较小值

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
const int N = 100008;


signed main () {
	std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
	string s;
	cin >> s;
	//不能有前导0所以特判第一个字符,如果为'9'这跳过
	if (s[0] != '9') {
		s[0] = (char)(min(9 - (s[0] - '0'), (s[0] - '0')) + '0'); //否则将这个取t和9-t更小的那个值
	}
	for (int i = 1; i < (int)s.size(); i++) {
		s[i] = (char)(min(9 - (s[i] - '0'), (s[i] - '0')) + '0'); //将s[i]更新为t和9-t中的较小值
	}
	cout << s << '\n';



	return 0;
}