目录
计算机组成原理部分:
爆肝到 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 -- 醉酒念诗文.