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

};
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值