Codeforces题解|1176C - Lose it!
题目信息 📚
【题目描述】
You are given an array $a$ consisting of $n$ integers. Each $a_i$ is one of the six following numbers: $4, 8, 15, 16, 23, 42$.
Your task is to remove the minimum number of elements to make this array good.
An array of length $k$ is called good if $k$ is divisible by $6$ and it is possible to split it into $\frac{k}{6}$ subsequences $4, 8, 15, 16, 23, 42$.
Examples of good arrays:
- $[4, 8, 15, 16, 23, 42]$ (the whole array is a required sequence);
- $[4, 8, 4, 15, 16, 8, 23, 15, 16, 42, 23, 42]$ (the first sequence is formed from first, second, fourth, fifth, seventh and tenth elements and the second one is formed from remaining elements);
- $[]$ (the empty array is good).
Examples of bad arrays:
- $[4, 8, 15, 16, 42, 23]$ (the order of elements should be exactly $4, 8, 15, 16, 23, 42$);
- $[4, 8, 15, 16, 23, 42, 4]$ (the length of the array is not divisible by $6$);
- $[4, 8, 15, 16, 23, 42, 4, 8, 15, 16, 23, 23]$ (the first sequence can be formed from first six elements but the remaining array cannot form the required sequence).
【输入】
The first line of the input contains one integer $n$ ($1 \le n \le 5 \cdot 10^5$) — the number of elements in $a$.
The second line of the input contains $n$ integers $a_1, a_2, \dots, a_n$ (each $a_i$ is one of the following numbers: $4, 8, 15, 16, 23, 42$), where $a_i$ is the $i$-th element of $a$.
【输出】
Print one integer — the minimum number of elements you have to remove to obtain a good array.
【输入样例1】
5
4 8 15 16 23
【输出样例1】
5
【输入样例2】
12
4 8 4 15 16 8 23 15 16 42 23 42
【输出样例2】
0
【输入样例3】
15
4 8 4 8 15 16 8 16 23 15 16 4 42 23 42
【输出样例3】
3
【题目来源】
https://codeforces.com/problemset/problem/1176/C
题目解析 🍉
【题目分析】
思维 + 统计
【C++代码】✅
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 5e5 + 10;
int a[N], n;
map<int, int> mp;
// 查找离散化下标
int findi(int x) {
int t[6] = {4, 8, 15, 16, 23, 42};
return lower_bound(t, t + 6, x) - t + 1;
}
int main() {
ios::sync_with_stdio(false); //cin读入优化
cin.tie(0);
cin >> n;
for (int i = 1; i <= n; i++) {
// 逐个读入元素
cin >> a[i];
int id = findi(a[i]);
mp[id]++;
// 判断当前元素,是否有合法个前置元素
// 如当前读到15,且map[findi(15)]=3,说明共有3个15
// 则前面至少有3个4和8,该15才合法
for (int i = 1; i < id; i++) {
if (mp[i] < mp[id]) {
mp[id]--;
break;
}
}
}
// 输出答案
int cnt = 0x3f3f3f3f;
for (int i = 1; i <= 6; i++) {
cnt = min(cnt, mp[i]);
}
cout << n - cnt * 6 << endl;
return 0;
}