1. 题目来源
2. 题目说明
3. 题目解析
方法一:排序+暴力优化+巧妙解法
这个得多读题,并且数据范围也是一个坑点。在 LeetCode
上很少会有卡数据的题目,也是对数据范围不敏感…疯狂超内存。
数据范围 n
达到了 1e9
看到这个数据范围还是放弃直接模拟吧,开辟空间进行硬模拟的话直接爆内存了。观察能够发现预定的位置其实很少只有 1e4
那么说明好多排其实没有被预定,那么就可以直接安排 2 个四人家庭。至此,暴力即可。
需要注意 sort()
配合 lambda
表达式进行二维数组的排序做法。也是很重要的一环。比赛着了魔,非得结构体硬整…结果就进入了死循环。简单理下思路:
- 以
rs
数组为出发点,采用sort
进行按行的排序,分别对各行进行处理,采用book
数组进行对预定位置进行记录,再次的for
循环读取一整行的预定位置也需要注意下 - 注意在此理论上设置最多存在
2n
个 4 人家庭。若该行 2—9 位置没有被预定,那么就能安排两个 4 人家庭,若被预定,则进行 3 种情况的分类讨论即可。
参见代码如下:
// 执行用时 :2380 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :229.4 MB, 在所有 C++ 提交中击败了100.00%的用户
class Solution {
public:
int maxNumberOfFamilies(int n, vector<vector<int>>& rs) {
int ans = n * 2, m = rs.size();
sort(rs.begin(), rs.end(), [](vector<int> a, vector<int> b) {return a[0] < b[0];});
bool book[20];
for (int i = 0; i < 15; ++i) book[i] = true;
for (int i = 0; i < m; ++i) {
book[rs[i][1]] = false;
if (i == m - 1 or rs[i][0] != rs[i + 1][0]) {
bool flag = true;
for (int k = 2; k <= 9; ++k) flag = flag && book[k];
if (flag == false) {
ans -= 2;
int ret = 0;
flag = true; for (int k = 2; k <= 5; ++k) flag = flag and book[k];
if (flag) ++ret;
flag = true; for (int k = 6; k <= 9; ++k) flag = flag and book[k];
if (flag) ++ret;
flag = true; for (int k = 4; k <= 7; ++k) flag = flag and book[k];
if (flag and ret == 0) ++ret;
ans += ret;
}
for (int i = 0; i < 15; ++i) book[i] = true;
}
}
return ans;
}
};