Leetcode 周赛299

6101. 判断矩阵是否是一个 X 矩阵

如果一个正方形矩阵满足下述 全部 条件,则称之为一个 X 矩阵 :

矩阵对角线上的所有元素都 不是 0
矩阵中所有其他元素都是 0
给你一个大小为 n x n 的二维整数数组 grid ,表示一个正方形矩阵。如果 grid 是一个 X 矩阵 ,返回 true ;否则,返回 false 。

示例 1:
在这里插入图片描述

输入:grid = [[2,0,0,1],[0,3,1,0],[0,5,2,0],[4,0,0,2]]
输出:true
解释:矩阵如上图所示。
X 矩阵应该满足:绿色元素(对角线上)都不是 0 ,红色元素都是 0 。
因此,grid 是一个 X 矩阵。

示例 2:
在这里插入图片描述

输入:grid = [[5,7,0],[0,3,1],[0,5,0]]
输出:false
解释:矩阵如上图所示。
X 矩阵应该满足:绿色元素(对角线上)都不是 0 ,红色元素都是 0 。
因此,grid 不是一个 X 矩阵。

提示:

n == grid.length == grid[i].length
3 <= n <= 100
0 <= grid[i][j] <= 105

模拟题

遍历一遍,判断两条对角线元素是否非0,其他元素是否全是0
主对角线:i == j

副对角线:i + j == n - 1(因为下标是从 0 开始的)

class Solution {
public:
    bool checkXMatrix(vector<vector<int>>& grid) {
        int row = grid.size();
        int col = grid[0].size();
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (j == i || j + i == row - 1) {
                    if (grid[i][j] == 0) {
                        return false;
                    }
                } else {
                    if (grid[i][j] != 0) {
                        return false;
                    }
                }
            }
        }
        
        return true;
    }
};

6100. 统计放置房子的方式数

一条街道上共有 n * 2 个 地块 ,街道的两侧各有 n 个地块。每一边的地块都按从 1 到 n 编号。每个地块上都可以放置一所房子。

现要求街道同一侧不能存在两所房子相邻的情况,请你计算并返回放置房屋的方式数目。由于答案可能很大,需要对 109 + 7 取余后再返回。

注意,如果一所房子放置在这条街某一侧上的第 i 个地块,不影响在另一侧的第 i 个地块放置房子。

示例 1:

输入:n = 1
输出:4
解释:
可能的放置方式:

  1. 所有地块都不放置房子。
  2. 一所房子放在街道的某一侧。
  3. 一所房子放在街道的另一侧。
  4. 放置两所房子,街道两侧各放置一所。

示例 2:

在这里插入图片描述

输入:n = 2
输出:9
解释:如上图所示,共有 9 种可能的放置方式。

提示:

1 <= n <= 104

动态规划

由题意可知,上下两侧互不影响,所以我们只需要算出一边的,然后平方就好了。
用 0 表示该位置没有放置房子,用1表示该位置放置了房子。
dp[i][0] = dp[i - 1][0] + dp[i - 1][1];
dp[i][1] = dp[i - 1][0];
当这个位置不放房子的时候,前一个位置可以有房子,也可以没有房子
当这个位置放置房子的时候,前一个位置只能是没有房子的。

最后的结果就是二者相加的平方
记得要在加的时候,和平方的时候mod一下。
而且为了防止爆int,可以开long long

class Solution {
public:
// 上下两边是不冲突的,可以只算一边,求个平方即可
    long long dp[10005][2];
    const int mod = 1e9 + 7;
    int countHousePlacements(int n) {
        dp[1][0] = 1;
        dp[1][1] = 1;
        for (int i = 2; i <= n; i++) {
            dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % mod;
            dp[i][1] = dp[i - 1][0] % mod;
        }
        long long t = dp[n][0] + dp[n][1];
        t = t * t % mod;
        return t;
    }
};

找规律

比赛的时候没太看懂题,n = 3的时候枚举错了,导致wa了,wa了两次之后,力扣有提示嘛,可以知道自己在哪个数据wa的,应该输出啥,才知道了 n = 5 时, 结果是169,是13的平方,联想到了斐波那契数列,这道题就是这样推出来的
从n = 3开始
s[n] = s[n - 1] + s[n - 2],且初始化s[1] = 2, s[2] = 3
计算结束之后再输出 平方即可

class Solution {
public:
    const int mod = 1e9 + 7;
    long long s[10005];
    int countHousePlacements(int n) {
        long long t = 0;
        s[1] = 2;
        s[2] = 3;
        for (int i = 3; i <= n; i++) {
            s[i] = s[i - 1] + s[i - 2];
            s[i] %= mod;
        }
        t = s[n] * s[n] % mod;
        int res = t;
        return res;
    }
};

5229. 拼接数组的最大分数

给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,长度都是 n 。

你可以选择两个整数 left 和 right ,其中 0 <= left <= right < n ,接着 交换 两个子数组 nums1[left…right] 和 nums2[left…right] 。

例如,设 nums1 = [1,2,3,4,5] 和 nums2 = [11,12,13,14,15] ,整数选择 left = 1 和 right = 2,那么 nums1 会变为 [1,12,13,4,5] 而 nums2 会变为 [11,2,3,14,15] 。
你可以选择执行上述操作 一次 或不执行任何操作。

数组的 分数 取 sum(nums1) 和 sum(nums2) 中的最大值,其中 sum(arr) 是数组 arr 中所有元素之和。

返回 可能的最大分数 。

子数组 是数组中连续的一个元素序列。arr[left…right] 表示子数组包含 nums 中下标 left 和 right 之间的元素(含 下标 left 和 right 对应元素)。

示例 1:

输入:nums1 = [60,60,60], nums2 = [10,90,10]
输出:210
解释:选择 left = 1 和 right = 1 ,得到 nums1 = [60,90,60] 和 nums2 = [10,60,10] 。
分数为 max(sum(nums1), sum(nums2)) = max(210, 80) = 210 。

示例 2:

输入:nums1 = [20,40,20,70,30], nums2 = [50,20,50,40,20]
输出:220
解释:选择 left = 3 和 right = 4 ,得到 nums1 = [20,40,20,40,20] 和 nums2 = [50,20,50,70,30] 。
分数为 max(sum(nums1), sum(nums2)) = max(140, 220) = 220 。

示例 3:

输入:nums1 = [7,11,13], nums2 = [1,1,1]
输出:31
解释:选择不交换任何子数组。
分数为 max(sum(nums1), sum(nums2)) = max(31, 3) = 31 。

提示:

n == nums1.length == nums2.length
1 <= n <= 105
1 <= nums1[i], nums2[i] <= 104

最大连续子序和

在这里插入图片描述
总体的思路还是最大连续子序和,只不过是对两个数组对应位置数值的差值求最大连续子列和。
最后的最大的和 = a数组和sum + c的最大连续子序和
求的时候可以贪心写,也可以dp推出来。
当前位置的最大连续子序和就是看 前一个位置的最大连续子序和 是否大于0,大于就加上当前值,否则就是当前值

class Solution {
public:
    int work(vector<int> &a, vector<int> &b) {
        int sum = 0;
        for (auto i : a) sum += i;
        
        int dt = 0, f = 0;
        for (int i = 0; i < a.size(); i++) {
            f = max(0, f) + b[i] - a[i];
            dt = max(f, dt);
        }
        
        return sum + dt;
    }
    
    int maximumsSplicedArray(vector<int>& a, vector<int>& b) {
        return max(work(a, b), work(b, a));
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
游戏说明:<br>一个5*5的方格 打算往每个格子里放房子,有4种颜色的房子 <br>蓝色的房子 占10人口 随便放在哪里都行 <br>红色的房子 占20人口 要求和蓝色的房子相邻 <br>绿色的房子 占30人口 要求和蓝色,红色的房子相邻 <br>黄色的房子 占40人口 要求和蓝色,红色,绿色的房子相邻 <br>问 如何放置 才能使5*5的格子占用的人口数量最大?<br><br>操作说明:<br>拉动各颜色的房子到欲放置的格子处释放鼠标,如果格子符合该颜色房子的需求则房子成功放入,否则房子不放入,如:欲放黄色房子,则本格子上下左右需存在蓝绿红三种房子。 <br>单击任何一个格子弹出该格子当前可放入的房子选项,双击房子即可放入,或者选中其中一个后按回车或点选择亦可放入。 <br>双击有房子的格子或房子即可拆掉此房子。 <br>键盘操作: <br>按上下左右箭头可在表格内移动,当前格子背景色为黑色,如无选中则从第一行第一列开始,按回车后选择房子,按Delete或“.”为拆掉房子。 <br>如果弹出选择房子时,上下左右箭头为选择当前格子可用的房子(如:向放黄色房子需先在需要放置的格子上下左右格放好蓝绿红房子,方可选择),按下回车后此房子加入格子内,Esc键为不做选择并关掉选择房子。 <br>如果拆除房子的邻居有对本房子要求时本房子不可拆除,需先拆除对于本房子做要求的房子,如:想拆掉蓝色房子,但上下左右有红色房子则需先拆掉红色房子方可拆掉蓝色房子。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值