“21 天好习惯”第一期-3

目录

计算机组成原理部分:

 leetcode每日一题:

nowcoder.ac ICPC 补题:


计算机组成原理部分:

爆肝到 2 点 , 8点又爬起来继续写 , 感觉身体被掏空.

第二章的 思维导图

 leetcode每日一题:

次元门

不会有人不会暴力吧 ? 不会吧 , 不会吧 .(可以去试一发 

class Solution { //c可过 , c++ vector 太慢了
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        for(int i=0;i<matrix.size();i++){
            for(int j=0;j<matrix[i].size();j++){
                if(target==matrix[i][j]) return true;
            }
        }
        return false;
    }
};

暴力解完题后开始优化: 二分查找 , 这不比暴力快 ???

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        for (const auto& row: matrix) {
            auto it = lower_bound(row.begin(), row.end(), target);
            if (it != row.end() && *it == target) {
                return true;
            }
        }
        return false;
    }
};

最优解: 二叉树 (BST) 因为严格满足 左孩子 小于 右孩子

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int n = matrix.size() , m = matrix[0].size();

        int left = m - 1 , right = 0;

        while(left >= 0 && right < n){
            if(matrix[right][left] == target) return true;
            else if(matrix[right][left] < target) right ++;
            else if(matrix[right][left] > target) left --;
            // left -- , right ++;
        }

        return false;
    }
};

nowcoder.ac ICPC 补题:

次元门

比赛时的 的想法 找到一个满足的点 , 那么以这个点右下角的矩形拥有的路线都是满足的这个右下角的矩形可以舍去遍历 ( 然而 dfs 和 bfs 都卡在了满足点为 [n][m] , 因为这要遍历所有路径.

bfs 超内存代码: 

#include <bits/stdc++.h>
using namespace std;
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define int long long
const int mod = 998244353;
struct node {
    int x, y, val0, val1;
};
int a[507][507];
int dp[507][507];
signed main() {
    ios;
    dp[1][0] = 1;
    for(int i = 1;i <= 500;i ++){
        for(int j = 1;j <= 500;j ++){
            dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
        }
    }
    int n, m, p1, q1;
    cin >> n >> m >> p1 >> q1;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) cin >> a[i][j];
    }
    queue<node> q;
    int v0 = 0, v1 = 0;
    if (a[1][1] == 0)
        v0 = 1;
    else
        v1 = 1;
    q.push({1, 1, v0, v1});
    int sum = 0;
    while (!q.empty()) {
        node start = q.front();
        q.pop();
        if (start.val0 >= p1 && start.val1 >= q1) {
            int ky = n - start.y + 1;
            int kx = m - start.x + 1;
            if (ky > kx) {
                swap(ky, kx);
            }
            if (ky ==1)
                sum++,sum%=mod;
            else
                sum = (sum + dp[ky][kx]) % mod;
            continue;
        }
        if (start.x + 1 <= m) {
            v0 = 0, v1 = 0;
            if (a[start.y][start.x + 1] == 0)
                v0 = 1;
            else
                v1 = 1;
            node next0 = {start.x + 1, start.y, start.val0 + v0,
                          start.val1 + v1};
            q.push(next0);
        }
        if (start.y + 1 <= n) {
            v0 = 0, v1 = 0;
            if (a[start.y + 1][start.x] == 0)
                v0 = 1;
            else
                v1 = 1;
            node next1 = {start.x, start.y + 1, start.val0 + v0,
                          start.val1 + v1};
            q.push(next1);
        }
    }
    cout << sum%mod << endl;
}

dfs 超时间代码:

#include <bits/stdc++.h>
using namespace std;
#define ios ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
const int mod = 998244353;
struct node {
    int x, y, val0, val1;
};
int a[507][507];
int dp[507][507];
long long sum = 0;
int m, n;
int p1, q1;
void dfs(int x, int y, int val0, int val1) {
    if (val0 >= p1 && val1 >= q1) {
        int kx = m - x + 1;
        int ky = n - y + 1;
        sum = (sum + dp[kx][ky]) % mod;
        return;
    }
    if (x + 1 <= m) {
        int v1 = 0, v2 = 0;
        if (a[y][x + 1] == 0)
            v1++;
        else
            v2++;
        dfs(x + 1, y, val0 + v1, val1 + v2);
    }
    if (y + 1 <= n) {
        int v1 = 0, v2 = 0;
        if (a[y + 1][x] == 0)
            v1++;
        else
            v2++;
        dfs(x, y + 1, val0 + v1, val1 + v2);
    }
}
signed main() {
    ios;
    dp[1][0] = 1;
    for (int i = 1; i <= 500; i++) {
        for (int j = 1; j <= 500; j++) {
            dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
        }
    }

    cin >> n >> m >> p1 >> q1;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) cin >> a[i][j];
    }
    int v1 = 0, v2 = 0;
    if (a[1][1] == 0)
        v1++;
    else
        v2++;
    dfs(1, 1, v1, v2);
    cout << sum % mod << endl;
}

正确思路: 三维dp , 保存每个点 每种情况的路径 , 但是 505 * 505 * 10000 依然会超出内存 , 所有要用滚动数组压缩 .

#include<bits/stdc++.h>
using namespace std;
const int mod = 998244353;
int Map[505][505] = {0};
int dp[2][505][10000] = {0};
int cut = 0;

signed main(void){
    int n , m , p , q; cin >> n >> m >> p >> q;
    for(int i = 1;i <= n;i ++) for(int j = 1;j <= m;j ++) cin >> Map[i][j];
    
    if(Map[1][1]) dp[1][1][0] = 1;
    else dp[1][1][1] = 1;
    
    for(int i = 1;i <= n;i ++){
        for(int j = 1;j <= m;j ++){
            if(i == 1 && j == 1) continue;
            for(int k = 0;k <= i + j - 1;k ++)
                if(!Map[i][j]) dp[i & 1][j][k] = (dp[(i + 1) & 1][j][k - 1] + dp[i & 1][j - 1][k - 1]) % mod;
                else dp[i & 1][j][k] = (dp[(i + 1) & 1][j][k] + dp[i & 1][j - 1][k]) % mod;
        }
    }
    
    for(int i = p;n + m - 1 - i >= q;i ++) cut = (cut + dp[n & 1][m][i]) % mod;
    
    cout << cut << endl;
    
    return 0;
}

(\\ V \\) 你可以迷茫 , 但不要虚度.Day Three -- 醉酒念诗文.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值