D357周赛复盘:模拟双端队列反转⭐⭐+贪心

news2025/2/25 23:10:14

文章目录

    • 2810.故障键盘
      • 1.直接用reverse解决
      • 2.双端队列
    • 2811.判断能否拆分数组(比较巧妙的贪心)
      • 思路
      • 完整版
    • 2812.找出最安全路径
    • 2810.故障键盘
      • 1.直接用reverse解决
      • 2.双端队列
    • 2811.判断能否拆分数组(比较巧妙的贪心)
      • 思路
      • 完整版
    • 2812.找出最安全路径

2810.故障键盘

你的笔记本键盘存在故障,每当你在上面输入字符 'i' 时,它会反转你所写的字符串。而输入其他字符则可以正常工作。

给你一个下标从 0 开始的字符串 s ,请你用故障键盘依次输入每个字符。

返回最终笔记本屏幕上输出的字符串。

示例 1:

输入:s = "string"
输出:"rtsng"
解释:
输入第 1 个字符后,屏幕上的文本是:"s" 。
输入第 2 个字符后,屏幕上的文本是:"st" 。
输入第 3 个字符后,屏幕上的文本是:"str" 。
因为第 4 个字符是 'i' ,屏幕上的文本被反转,变成 "rts" 。
输入第 5 个字符后,屏幕上的文本是:"rtsn" 。
输入第 6 个字符后,屏幕上的文本是: "rtsng" 。
因此,返回 "rtsng" 。

示例 2:

输入:s = "poiinter"
输出:"ponter"
解释:
输入第 1 个字符后,屏幕上的文本是:"p" 。
输入第 2 个字符后,屏幕上的文本是:"po" 。
因为第 3 个字符是 'i' ,屏幕上的文本被反转,变成 "op" 。
因为第 4 个字符是 'i' ,屏幕上的文本被反转,变成 "po" 。
输入第 5 个字符后,屏幕上的文本是:"pon" 。
输入第 6 个字符后,屏幕上的文本是:"pont" 。
输入第 7 个字符后,屏幕上的文本是:"ponte" 。
输入第 8 个字符后,屏幕上的文本是:"ponter" 。
因此,返回 "ponter" 。

提示:

  • 1 <= s.length <= 100
  • s 由小写英文字母组成
  • s[0] != 'i'

1.直接用reverse解决

反转字符串可以直接用reverse来解决,如下:

class Solution {
public:
    string finalString(string s) {
        string result=" ";
        for(char c:s){
            if(c=='i'){
                reverse(result.begin(),result.end());
            }
            else{
                result.push_back(c);
            }
        }
        return result;
    }
};

2.双端队列

遇到字符i时,可以通过栈来实现字符串反转的效果。这是因为栈是后进先出(LIFO)的数据结构,它可以帮助我们将之前输入的字符逆序输出。

但是,用栈的话,无法处理字符串本身没有i这种情况,因此应该使用双端队列。

双端队列思路:

  1. 初始化一个双端队列 deque<char> q:双端队列允许我们在队列的头部和尾部都进行添加和删除操作。

  2. 使用一个布尔变量 right 来确定插入的方向:当 righttrue 时,我们在队列的尾部插入字符;当 rightfalse 时,我们在队列的头部插入字符。

  3. 遍历输入的字符串 s 中的每个字符

    • 如果字符是 ‘i’:则将 right 的值取反,即改变插入方向。因此,如果之前是在尾部插入,现在就在头部插入,反之亦然。
    • 如果字符不是 ‘i’ 且 righttrue:则在双端队列的尾部插入该字符。
    • 如果字符不是 ‘i’ 且 rightfalse:则在双端队列的头部插入该字符。
  4. 将双端队列 q 转化为字符串 result:这里,利用了字符串的迭代器构造函数,将 q 的所有字符转化为一个字符串。

  5. 检查最后的插入方向:如果最后的插入方向是在头部(即 rightfalse),说明队列中的字符序列是相反的,因此我们需要将 result 反转。

  6. 返回结果字符串 result

    关键思想是,利用双端队列模拟字符串的插入过程,每当遇到字符 ‘i’ 时,改变插入的方向。这种方法的效率很高,因为在双端队列的头部和尾部插入字符的时间复杂度都是 O(1)

class Solution {
public:
    string finalString(string s) {
        //双端队列
        deque<char>q;
        bool right = true;//设定一个量用来修改添加方向
        for(char c:s){
            if(c=='i'){
                right=!right;//方向返过来,而且i本身是不管的,所以可以直接else if
            }
            else if(right){
                q.push_back(c);
            }
            else {
                q.push_front(c);
            }
        }
        string result(q.begin(),q.end());//可以直接把双端队列放在字符串里

        if(!right){//有偶数个i的时候,实际上最后的result是不变的,直接看right是不是true就可以
            reverse(result.begin(),result.end());
        }
        return result;

    }
};

2811.判断能否拆分数组(比较巧妙的贪心)

给你一个长度为 n 的数组 nums 和一个整数 m 。请你判断能否执行一系列操作,将数组拆分成 n非空 数组。

在每一步操作中,你可以选择一个 长度至少为 2 的现有数组(之前步骤的结果) 并将其拆分成 2 个子数组,而得到的 每个 子数组,至少 需要满足以下条件之一:

  • 子数组的长度为 1 ,或者
  • 子数组元素之和 大于或等于 m

如果你可以将给定数组拆分成 n 个满足要求的数组,返回 true ;否则,返回 false

**注意:**子数组是数组中的一个连续非空元素序列。

示例 1:

输入:nums = [2, 2, 1], m = 4
输出:true
解释:
第 1 步,将数组 nums 拆分成 [2, 2] 和 [1] 。
第 2 步,将数组 [2, 2] 拆分成 [2] 和 [2] 。
因此,答案为 true 。

示例 2:

输入:nums = [2, 1, 3], m = 5 
输出:false
解释:
存在两种不同的拆分方法:
第 1 种,将数组 nums 拆分成 [2, 1] 和 [3] 。
第 2 种,将数组 nums 拆分成 [2] 和 [1, 3] 。
然而,这两种方法都不满足题意。因此,答案为 false 。

示例 3:

输入:nums = [2, 3, 3, 2, 3], m = 6
输出:true
解释:
第 1 步,将数组 nums 拆分成 [2, 3, 3, 2] 和 [3] 。
第 2 步,将数组 [2, 3, 3, 2] 拆分成 [2, 3, 3] 和 [2] 。
第 3 步,将数组 [2, 3, 3] 拆分成 [2] 和 [3, 3] 。
第 4 步,将数组 [3, 3] 拆分成 [3] 和 [3] 。
因此,答案为 true 。 

提示:

  • 1 <= n == nums.length <= 100
  • 1 <= nums[i] <= 100
  • 1 <= m <= 200

思路

这道题用的是贪心的思想,只要有两个连续的数字加起来>=m,就可以把除了这俩之外的都拆出去。

也就是说,只要有一组连续数字相加>=m,那么一定可以满足条件2。条件1是一定可以满足的,需要满足的是有两个连续的数字相加>=m。这样最后才能拆出来两个1。

完整版

class Solution {
public:
    bool canSplitArray(vector<int>& nums, int m) {
        if(nums.size()==1||nums.size()==2){
            return true;
        }
        for(int i=0;i<nums.size()-1;i++){
            if(nums[i]+nums[i+1]>=m){
                return true;
            }
        }
        return false;
    }
};

这是一种很巧妙的贪心,主要是这道题两个条件满足一个即可,而且数组全是正整数,有两个相加>=m,最后结果一定>=m。

2812.找出最安全路径

给你一个下标从 0 开始、大小为 n x n 的二维矩阵 grid ,其中 (r, c) 表示:

  • 如果 grid[r][c] = 1 ,则表示一个存在小偷的单元格
  • 如果 grid[r][c] = 0 ,则表示一个空单元格

你最开始位于单元格 (0, 0) 。在一步移动中,你可以移动到矩阵中的任一相邻单元格,包括存在小偷的单元格。

矩阵中路径的 安全系数 定义为:从路径中任一单元格到矩阵中任一小偷所在单元格的 最小 曼哈顿距离。

返回所有通向单元格 (n - 1, n - 1) 的路径中的 最大安全系数

单元格 (r, c) 的某个 相邻 单元格,是指在矩阵中存在的 (r, c + 1)(r, c - 1)(r + 1, c)(r - 1, c) 之一。

两个单元格 (a, b)(x, y) 之间的 曼哈顿距离 等于 | a - x | + | b - y | ,其中 |val| 表示 val 的绝对值。

示例 1:

2810.故障键盘

你的笔记本键盘存在故障,每当你在上面输入字符 'i' 时,它会反转你所写的字符串。而输入其他字符则可以正常工作。

给你一个下标从 0 开始的字符串 s ,请你用故障键盘依次输入每个字符。

返回最终笔记本屏幕上输出的字符串。

示例 1:

输入:s = "string"
输出:"rtsng"
解释:
输入第 1 个字符后,屏幕上的文本是:"s" 。
输入第 2 个字符后,屏幕上的文本是:"st" 。
输入第 3 个字符后,屏幕上的文本是:"str" 。
因为第 4 个字符是 'i' ,屏幕上的文本被反转,变成 "rts" 。
输入第 5 个字符后,屏幕上的文本是:"rtsn" 。
输入第 6 个字符后,屏幕上的文本是: "rtsng" 。
因此,返回 "rtsng" 。

示例 2:

输入:s = "poiinter"
输出:"ponter"
解释:
输入第 1 个字符后,屏幕上的文本是:"p" 。
输入第 2 个字符后,屏幕上的文本是:"po" 。
因为第 3 个字符是 'i' ,屏幕上的文本被反转,变成 "op" 。
因为第 4 个字符是 'i' ,屏幕上的文本被反转,变成 "po" 。
输入第 5 个字符后,屏幕上的文本是:"pon" 。
输入第 6 个字符后,屏幕上的文本是:"pont" 。
输入第 7 个字符后,屏幕上的文本是:"ponte" 。
输入第 8 个字符后,屏幕上的文本是:"ponter" 。
因此,返回 "ponter" 。

提示:

  • 1 <= s.length <= 100
  • s 由小写英文字母组成
  • s[0] != 'i'

1.直接用reverse解决

反转字符串可以直接用reverse来解决,如下:

class Solution {
public:
    string finalString(string s) {
        string result=" ";
        for(char c:s){
            if(c=='i'){
                reverse(result.begin(),result.end());
            }
            else{
                result.push_back(c);
            }
        }
        return result;
    }
};

2.双端队列

遇到字符i时,可以通过栈来实现字符串反转的效果。这是因为栈是后进先出(LIFO)的数据结构,它可以帮助我们将之前输入的字符逆序输出。

但是,用栈的话,无法处理字符串本身没有i这种情况,因此应该使用双端队列。

双端队列思路:

  1. 初始化一个双端队列 deque<char> q:双端队列允许我们在队列的头部和尾部都进行添加和删除操作。

  2. 使用一个布尔变量 right 来确定插入的方向:当 righttrue 时,我们在队列的尾部插入字符;当 rightfalse 时,我们在队列的头部插入字符。

  3. 遍历输入的字符串 s 中的每个字符

    • 如果字符是 ‘i’:则将 right 的值取反,即改变插入方向。因此,如果之前是在尾部插入,现在就在头部插入,反之亦然。
    • 如果字符不是 ‘i’ 且 righttrue:则在双端队列的尾部插入该字符。
    • 如果字符不是 ‘i’ 且 rightfalse:则在双端队列的头部插入该字符。
  4. 将双端队列 q 转化为字符串 result:这里,利用了字符串的迭代器构造函数,将 q 的所有字符转化为一个字符串。

  5. 检查最后的插入方向:如果最后的插入方向是在头部(即 rightfalse),说明队列中的字符序列是相反的,因此我们需要将 result 反转。

  6. 返回结果字符串 result

    关键思想是,利用双端队列模拟字符串的插入过程,每当遇到字符 ‘i’ 时,改变插入的方向。这种方法的效率很高,因为在双端队列的头部和尾部插入字符的时间复杂度都是 O(1)

class Solution {
public:
    string finalString(string s) {
        //双端队列
        deque<char>q;
        bool right = true;//设定一个量用来修改添加方向
        for(char c:s){
            if(c=='i'){
                right=!right;//方向返过来,而且i本身是不管的,所以可以直接else if
            }
            else if(right){
                q.push_back(c);
            }
            else {
                q.push_front(c);
            }
        }
        string result(q.begin(),q.end());//可以直接把双端队列放在字符串里

        if(!right){//有偶数个i的时候,实际上最后的result是不变的,直接看right是不是true就可以
            reverse(result.begin(),result.end());
        }
        return result;

    }
};

2811.判断能否拆分数组(比较巧妙的贪心)

给你一个长度为 n 的数组 nums 和一个整数 m 。请你判断能否执行一系列操作,将数组拆分成 n非空 数组。

在每一步操作中,你可以选择一个 长度至少为 2 的现有数组(之前步骤的结果) 并将其拆分成 2 个子数组,而得到的 每个 子数组,至少 需要满足以下条件之一:

  • 子数组的长度为 1 ,或者
  • 子数组元素之和 大于或等于 m

如果你可以将给定数组拆分成 n 个满足要求的数组,返回 true ;否则,返回 false

**注意:**子数组是数组中的一个连续非空元素序列。

示例 1:

输入:nums = [2, 2, 1], m = 4
输出:true
解释:
第 1 步,将数组 nums 拆分成 [2, 2] 和 [1] 。
第 2 步,将数组 [2, 2] 拆分成 [2] 和 [2] 。
因此,答案为 true 。

示例 2:

输入:nums = [2, 1, 3], m = 5 
输出:false
解释:
存在两种不同的拆分方法:
第 1 种,将数组 nums 拆分成 [2, 1] 和 [3] 。
第 2 种,将数组 nums 拆分成 [2] 和 [1, 3] 。
然而,这两种方法都不满足题意。因此,答案为 false 。

示例 3:

输入:nums = [2, 3, 3, 2, 3], m = 6
输出:true
解释:
第 1 步,将数组 nums 拆分成 [2, 3, 3, 2] 和 [3] 。
第 2 步,将数组 [2, 3, 3, 2] 拆分成 [2, 3, 3] 和 [2] 。
第 3 步,将数组 [2, 3, 3] 拆分成 [2] 和 [3, 3] 。
第 4 步,将数组 [3, 3] 拆分成 [3] 和 [3] 。
因此,答案为 true 。 

提示:

  • 1 <= n == nums.length <= 100
  • 1 <= nums[i] <= 100
  • 1 <= m <= 200

思路

这道题用的是贪心的思想,只要有两个连续的数字加起来>=m,就可以把除了这俩之外的都拆出去。

也就是说,只要有一组连续数字相加>=m,那么一定可以满足条件2。条件1是一定可以满足的,需要满足的是有两个连续的数字相加>=m。这样最后才能拆出来两个1。

完整版

class Solution {
public:
    bool canSplitArray(vector<int>& nums, int m) {
        if(nums.size()==1||nums.size()==2){
            return true;
        }
        for(int i=0;i<nums.size()-1;i++){
            if(nums[i]+nums[i+1]>=m){
                return true;
            }
        }
        return false;
    }
};

这是一种很巧妙的贪心,主要是这道题两个条件满足一个即可,而且数组全是正整数,有两个相加>=m,最后结果一定>=m。

2812.找出最安全路径

给你一个下标从 0 开始、大小为 n x n 的二维矩阵 grid ,其中 (r, c) 表示:

  • 如果 grid[r][c] = 1 ,则表示一个存在小偷的单元格
  • 如果 grid[r][c] = 0 ,则表示一个空单元格

你最开始位于单元格 (0, 0) 。在一步移动中,你可以移动到矩阵中的任一相邻单元格,包括存在小偷的单元格。

矩阵中路径的 安全系数 定义为:从路径中任一单元格到矩阵中任一小偷所在单元格的 最小 曼哈顿距离。

返回所有通向单元格 (n - 1, n - 1) 的路径中的 最大安全系数

单元格 (r, c) 的某个 相邻 单元格,是指在矩阵中存在的 (r, c + 1)(r, c - 1)(r + 1, c)(r - 1, c) 之一。

两个单元格 (a, b)(x, y) 之间的 曼哈顿距离 等于 | a - x | + | b - y | ,其中 |val| 表示 val 的绝对值。

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

输入:grid = [[1,0,0],[0,0,0],[0,0,1]]
输出:0
解释:从 (0, 0) 到 (n - 1, n - 1) 的每条路径都经过存在小偷的单元格 (0, 0) 和 (n - 1, n - 1) 。

示例 2:

在这里插入图片描述

输入:grid = [[0,0,1],[0,0,0],[0,0,0]]
输出:2
解释:
上图所示路径的安全系数为 2:
- 该路径上距离小偷所在单元格(0,2)最近的单元格是(0,0)。它们之间的曼哈顿距离为 | 0 - 0 | + | 0 - 2 | = 2 。
可以证明,不存在安全系数更高的其他路径。

示例 3:

在这里插入图片描述

输入:grid = [[0,0,0,1],[0,0,0,0],[0,0,0,0],[1,0,0,0]]
输出:2
解释:
上图所示路径的安全系数为 2:
- 该路径上距离小偷所在单元格(0,3)最近的单元格是(1,2)。它们之间的曼哈顿距离为 | 0 - 1 | + | 3 - 2 | = 2 。
- 该路径上距离小偷所在单元格(3,0)最近的单元格是(3,2)。它们之间的曼哈顿距离为 | 3 - 3 | + | 0 - 2 | = 2 。
可以证明,不存在安全系数更高的其他路径。

提示:

  • 1 <= grid.length == n <= 400
  • grid[i].length == n
  • grid[i][j]01
  • grid 至少存在一个小偷

这道题是bfs,笔试考的比较多。先记录一下做法。

class Solution {
public:
    int maximumSafenessFactor(vector<vector<int>>& grid) {
        int n = grid.size();
        vector<vector<int>> dist(n, vector<int>(n, INT_MAX));
        vector<vector<int>> safe(n, vector<int>(n, 0));
        queue<pair<int, int>> q;

        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) {
                    dist[i][j] = 0;
                    q.push({i, j});
                }
            }
        }

        vector<vector<int>> dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
        while (!q.empty()) {
            int r = q.front().first, c = q.front().second;
            q.pop();
            for (auto &dir : dirs) {
                int nr = r + dir[0], nc = c + dir[1];
                if (nr >= 0 && nr < n && nc >= 0 && nc < n && dist[r][c] + 1 < dist[nr][nc]) {
                    dist[nr][nc] = dist[r][c] + 1;
                    q.push({nr, nc});
                }
            }
        }

        safe[n-1][n-1] = dist[n-1][n-1];
        q.push({n-1, n-1});
        while (!q.empty()) {
            int r = q.front().first, c = q.front().second;
            q.pop();
            for (auto &dir : dirs) {
                int nr = r + dir[0], nc = c + dir[1];
                if (nr >= 0 && nr < n && nc >= 0 && nc < n) {
                    int newSafe = min(safe[r][c], dist[nr][nc]);
                    if (newSafe > safe[nr][nc]) {
                        safe[nr][nc] = newSafe;
                        q.push({nr, nc});
                    }
                }
            }
        }

        return safe[0][0];
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/960533.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OS | 4 抽象:进程

OS | 4 抽象&#xff1a;进程 文章目录 OS | 4 抽象&#xff1a;进程CPU虚拟化的方法进程&#xff1a;是一种抽象非正式定义 进程的机器状态 进程API程序转换为进程的过程进程状态>>>>> 欢迎关注公众号【三戒纪元】 <<<<< CPU虚拟化的方法 操作…

分布式调度Elastic-job

分布式调度Elastic-job 1. 概述 1.1什么是任务调度 我们可以思考⼀下下⾯业务场景的解决⽅案: 某电商平台需要每天上午10点&#xff0c;下午3点&#xff0c;晚上8点发放⼀批优惠券某银⾏系统需要在信⽤卡到期还款⽇的前三天进⾏短信提醒某财务系统需要在每天凌晨0:10分结算前…

进程控制相关 API-创建进程、进程分离、进程退出、进程阻塞

进程控制相关 API p.s 进程控制中的状态转换 相关 API&#xff0c;用户很少用到&#xff0c;在此不提。 一般来说&#xff0c;这些内核标准 API&#xff0c;在执行出错&#xff08;可能是资源不够、权限不够等等&#xff09;会返回负值&#xff08;比如 -1&#xff09;&#…

Go实现LogAgent:海量日志收集系统【上篇——LogAgent实现】

Go实现LogAgent 项目架构图&#xff1a; 0 项目背景与方案选择 背景 当公司发展的越来越大&#xff0c;业务越来越复杂时&#xff0c;每个业务系统都有自己的日志。此时我们就应该将不同业务线的日志进行实时收集&#xff0c;存储到一个日志收集中心&#xff0c;最后再通过…

手写Mybatis:第7章-SQL执行器的定义和实现

文章目录 一、目标&#xff1a;SQL执行的定义和实现二、设计&#xff1a;SQL执行的定义和实现三、实现&#xff1a;SQL执行的定义和实现3.1 工程结构3.2 SQL执行实现的关系图3.3 执行器的定义和实现3.3.1 Executor 接口3.3.2 BaseExecutor 抽象基类3.3.3 SimpleExecutor 简单执…

编译工具:CMake(六) | 使用外部共享库和头文件

编译工具&#xff1a;CMake&#xff08;六&#xff09; | 使用外部共享库和头文件 步骤引入头文件搜索路径为 target 添加共享库 步骤 在/Compilation_tool/cmake 目录建立 t4 目录 建立src目录&#xff0c;编写源文件main.c&#xff0c;内容如下&#xff1a; #include <…

ModaHub魔搭社区——决胜大模型时代,算力、网络、向量数据库缺一不可

大模型应用场景日趋多样,需求也随着增加,进而倒逼着多元算力方面的创新,为满足AI工作负载的需求,采用GPU、FPGA、ASIC等加速卡的服务器越来越多。 根据IDC数据统计,2022年,中国加速服务器市场相比2019年增长44.0亿美元,服务器市场增量的一半更是来自加速服务器。 这意味…

shell bash中设置命令set

1 Preface/Foreword set命令用于shell脚本在执行命令时候&#xff0c;遇到异常的处理机制。 2 Usage 2.1 set -e 当执行命令过程中遇到异常&#xff0c;那么就退出脚本&#xff0c;不会往下执行其它命令。 #!/bin/bash #set -eroot GIT_TAG${CI_BUILD_TAG-NOTAG} GIT_REV…

MySQL创建用户时报错“Your password does not satisfy the current policy requirements“

MySQL创建用户时报错"Your password does not satisfy the current policy requirements" MySQL是一个流行的关系型数据库管理系统&#xff0c;它提供了许多安全性特性&#xff0c;其中之一是密码策略。在创建或更改用户密码时&#xff0c;MySQL会检查密码是否符合当…

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉农大图书馆

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉农大图书馆

HCIP---BGP协议

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 根据AS自治系统可以将动态路由协议划分为IGP和EGP协议。IGP协议是应用在AS内部&#…

手摸手2-springboot编写基础的增删改查

目录 手摸手2-springboot编写基础的增删改查创建controller层添加service层接口service层实现添加mapper层mapper层对应的sql添加扫描注解,对应sql文件的目录 手摸手2-springboot编写基础的增删改查 创建controller层 实现 test 表中的添加、修改、删除及列表查询接口&#x…

PHP8函数包含文件-PHP8知识详解

在php中&#xff0c;可以使用以下函数来包含其他文件&#xff1a;include()、include_once()、require()、require_once()。 1、include(): 包含并运行指定文件中的代码。如果文件不存在或包含过程中出现错误&#xff0c;将发出警告。 <?php include filename.php; ?>…

【前端demo】背景渐变动画

文章目录 效果过程代码htmlcss 其他demo 效果 效果预览&#xff1a;https://codepen.io/karshey/pen/OJrXZwQ 过程 注意&#xff0c;直接在body上加height:100%可能也会出现height为0的情况&#xff0c;这是需要令html的height:100% 代码 html <!DOCTYPE html> <…

面试题--从键盘输入网站到网页显示,之间发生了什么

文章目录 首先进入HTTP阶段协议栈阶段TCP阶段IP阶段MAC网卡交换机路由器抵达 首先进入HTTP阶段 1.解析对应的URL&#xff0c;访问一个对应的服务器xxx.com的一个文件index.html; 2 使用DNS查询对应的ip地址&#xff0c;通过DNS服务器进行查找 3 组装http报文&#xff0c;生成h…

成集云 | 多维表自动查询快递100信息 | 解决方案

源系统成集云目标系统 方案介绍 产品详情 维格表是一种新一代的团队数据协作和项目管理工具&#xff0c;它结合了可视化数据库、电子表格、实时网络协同、低代码开发技术四项功能&#xff0c;且支持API与可视化看板&#xff0c;操作简单&#xff0c;能提升中小企业的数字化生…

python网络编程

文章目录 socket套接字客户端/服务模型linux文件描述符fdLinux网络IO模型详解网络服务器Apache VS Nginx生产者消费者-生成器版客户端/服务端-多线程版IO多路复用TCPServer模型异步IO多路复用TCPServer模型 socket套接字 套接字&#xff08;socket&#xff09;是抽象概念,表示T…

【数据分享】1901-2022年1km分辨率的逐月降水栅格数据(免费获取/全国/分省)

气象指标在日常研究中非常常用&#xff0c;之前我们给大家分享过来源于国家青藏高原科学数据中心提供的气象指标栅格数据&#xff08;均可查看之前的文章获悉详情&#xff09;&#xff1a; 1901-2022年1km分辨率逐月平均气温栅格数据1901-2022年1km分辨率逐年平均气温栅格数据…

wsl中使用宝塔每次都要绑定账号问题解决

环境&#xff1a;windows11、wsl2、Ubuntu20.04、宝塔8.0.24 1、开启Hyper-V&#xff0c;如果是家庭版使用下面代码启用Hyper-V&#xff0c;创建个.cmd文件保存后使用管理员权限运行&#xff08;需要重启电脑&#xff09; pushd "%~dp0" dir /b %SystemRoot%\servi…

QT6配置Android环境的多次尝试

可能用到的链接&#xff1a;https://www.androiddevtools.cn/#&#xff08;Android开发工具&#xff09; https://developer.android.google.cn/studio&#xff08;Android studio 下载&#xff09; https://www.oracle.com/java/technologies/downloads&#xff08;java下载&a…