贪心专题题目讲解
贪心专题题目讲解
学习网站:OI维基
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
链接
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
链接
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
链接
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
链接
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
链接
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;
}