[LeetCode 双周赛22] 2. 安排电影院座位(排序、暴力优化、巧妙解法)

1. 题目来源

链接:5349. 安排电影院座位

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;
    }

};
发布了391 篇原创文章 · 获赞 329 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/yl_puyu/article/details/105037028