当前位置: 首页 > news >正文

笔试强训题(2)

目录

  • 1. Day07
    • 1.1 在字符串中找出连续最长的数字串(模拟 + 双指针)
    • 1.2 岛屿数量(BFS / DFS)
    • 1.3 拼三角(枚举 / dfs)
  • 2. Day08
    • 2.1 求最小公倍数(数学)
    • 2.2 数组中的最长连续子序列(排序 + 模拟)
    • 2.3 字目收集(动态规划 - 路径问题)
  • 3. Day09
    • 3.1 添加逗号(模拟)
    • 3.2 跳台阶(动态规划)
    • 3.3 扑克牌顺子(排序)
  • 4. Day10
    • 4.1 最长回文子串(回文串)
    • 4.2 买卖股票的最好时机(一)(贪心)
    • 4.3 过河卒(动态规划 - 路径问题)
  • 5. Day11
    • 5.1 游游的水果大礼包(枚举)
    • 5.2 买卖股票的最好时机(二)(贪心)
    • 5.3 倒置字符串(字符串)
  • 6. Day12
    • 6.1 删除公共字符(哈希)
    • 6.2 两个链表的第⼀个公共结点(链表)
    • 6.3 mari和shiny(动态规划 - 线性dp)

1. Day07

1.1 在字符串中找出连续最长的数字串(模拟 + 双指针)

  1. 题目链接: 在字符串中找出连续最长的数字串
  2. 题目描述:

  1. 解法:
    • 算法思路双指针:
      • 遍历整个字符串,遇到数字的时候,用双指针找出这段连续的数字子串,根据此时的长度更新起始位置和长度。
  2. C++ 算法代码:
#include <iostream>
using namespace std;

int main() 
{
    string str;
    cin >> str;
    int left = 0;
    int right = 0;

    int retleft = 0;
    int retright = 0;
    while(right < str.size())
    {
        if(str[right] <= '9' && str[right] >= '0')
        {
            if(right - left > retright - retleft)
            {
                retright = right;
                retleft = left;
            }

            right++;
        }
        else 
        {
            right++;
            left = right;
        }
    }

    cout << str.substr(retleft, retright - retleft + 1) << endl;

    return 0;
}

1.2 岛屿数量(BFS / DFS)

  1. 题目链接: NC109 岛屿数量
  2. 题目描述:

  1. 解法:
    • 算法思路:经典的 floodfill 算法。用 dfs 或者是 bfs 找出⼀个联通的区域,并且标记上。看看⼀共能找出几个联通块。
  2. C++ 算法代码:
class Solution {
public:
    int dx[4] = {0, 1, -1, 0};
    int dy[4] = {1, 0, 0, -1};
    int m = 0;
    int n = 0;

    int solve(vector<vector<char> >& grid) 
    {
        int ret = 0;
        m = grid.size();
        n = grid[0].size();
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(grid[i][j] == '1')
                {
                    ret++;
                    dfs(grid, i, j);
                }
            }
        }

        return ret;
    }

    void dfs(vector<vector<char>>& grid, int i, int j)
    {
        grid[i][j] = '0';
        for(int k = 0; k < 4; k++)
        {
            int x = i + dx[k];
            int y = j + dy[k];
            if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1')
            {
                dfs(grid, x, y);
            }
        }
    }
};

1.3 拼三角(枚举 / dfs)

  1. 题目链接: 拼三角
  2. 题目描述:

  1. 解法:
    • 算法思路:简单枚举,不过有很多种枚举方法,我们这里直接用简单粗暴的枚举方式。
  2. C++ 算法代码:
include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    int t = 0;
    cin >> t; 
    int arr[6];
    while(t--)
    {
        for(int i = 0; i < 6; i++)
        {
            cin >> arr[i];
        }
        
        sort(arr, arr + 6);
        if(arr[0] + arr[1] > arr[2] && arr[3] + arr[4] > arr[5] ||
           arr[0] + arr[2] > arr[3] && arr[1] + arr[4] > arr[5] ||
           arr[0] + arr[3] > arr[4] && arr[1] + arr[2] > arr[5] ||
           arr[0] + arr[4] > arr[5] && arr[1] + arr[2] > arr[3])
        {
            cout << "Yes" << endl;
        }
        else
        {
            cout << "No" << endl;
        }
    }
    
    return 0;
}

2. Day08

2.1 求最小公倍数(数学)

  1. 题目链接: HJ108 求最小公倍数
  2. 题目描述:

  1. 解法:
    • 算法思路:A 和 B 的最小公倍数 = A * B / 两者的最大公约数。 最大公约数:辗转相除法。
  2. C++ 算法代码:
#include <iostream>
using namespace std;

int gcd(int a, int b)
{
    if(b == 0)
    {
        return a;
    }
    
    return gcd(b, a % b);
}

int main() 
{
    int a = 0;
    int b = 0;
    cin >> a >> b;

    cout << (a * b / gcd(a, b)) << endl;

    return 0;
}

2.2 数组中的最长连续子序列(排序 + 模拟)

  1. 题目链接: NC95 数组中的最长连续子序列
  2. 题目描述:

  1. 解法:
    • 算法思路:排序 + 模拟 。但是要注意处理数字相同的情况!
  2. C++ 算法代码:
class Solution {
public:

    int MLS(vector<int>& arr) 
    {
        sort(arr.begin(), arr.end());

        int n = arr.size();
        int ret = 0;
        int tmp = 1;
        for(int i = 0; i < n - 1; i++)
        {
            if(arr[i + 1] - arr[i] == 1)
            {
                tmp++;
                if(tmp > ret)
                {
                    ret = tmp;
                }
            }
            else if(arr[i + 1] - arr[i] == 0)
            {
                continue;
            }
            else 
            {
                tmp = 1;
            }
        }

        return ret;
    }
};

2.3 字目收集(动态规划 - 路径问题)

  1. 题目链接: DP39 字母收集
  2. 题目描述:

  1. 解法:
    • 算法思路:基础的路径问题的 dp 模型。
  2. C++ 算法代码:
#include <iostream>
using namespace std;

const int N = 510;
char g[N][N];
int dp[N][N];
int m = 0;
int n = 0;

int main() 
{
    cin >> m >> n;
    for(int i = 1; i <= m; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            cin >> g[i][j];
        }
    }

    for(int i = 1; i <= m; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            int tmp = 0;
            if(g[i][j] == 'l')
            {
                tmp = 4;
            }
            else if(g[i][j] == 'o')
            {
                tmp = 3;
            }
            else if(g[i][j] == 'v')
            {
                tmp = 2;
            }
            else if(g[i][j] == 'e')
            {
                tmp = 1;
            }

            dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + tmp;
        }
    }

    cout << dp[m][n] << endl;

    return 0;
}

3. Day09

3.1 添加逗号(模拟)

  1. 题目链接: BC146 添加逗号
  2. 题目描述:

  1. 解法:
    • 算法思路:可以从后往前遍历这个数,每提取三个数字的时候,加⼀个逗号。最后处理⼀下边界情况即可。
  2. C++ 算法代码:
#include <iostream>
using namespace std;

int main() 
{
    string s;
    cin >> s;
    string ret;

    int n = s.size();
    for(int i = 0; i < n; i++)
    {
        ret += s[i];
        if((n - i - 1) % 3 == 0 && i != n - 1)
        {
            ret += ',';
        }
    }

    cout << ret << endl;

    return 0;
}

3.2 跳台阶(动态规划)

  1. 题目链接: DP2 跳台阶
  2. 题目描述:

  1. 解法:
    • 算法思路:最入门的动态规划问题,不必多说…
  2. C++ 算法代码:
#include <iostream>
using namespace std;

const int N = 41;

int main() 
{
    int n = 0;
    cin >> n;

    int dp[N] = {0};
    dp[0] = 1;
    dp[1] = 1;
    for(int i = 2; i <= n; i++)
    {
        dp[i] = dp[i - 1] + dp[i - 2];
    }

    cout << dp[n] << endl;

    return 0;
}

3.3 扑克牌顺子(排序)

  1. 题目链接: 扑克牌顺子
  2. 题目描述:

  1. 解法:
    • 规律:如果能够构成顺子的话,所有的非零元素应该满足下面两个条件:
      • 不能出现重复元素;
      • max - min <= 4
  2. C++ 算法代码:
class Solution {
public:

    bool IsContinuous(vector<int>& numbers) 
    {
        sort(numbers.begin(), numbers.end());
        int hash[14] = {0};

        for(int j = 0; j < 5; j++)
        {
            if(numbers[j] == 0)
            {
                continue;
            }

            if(numbers[4] - numbers[j] > 4)
            {
                return false;
            }
            else
            {
                break;
            }
        }

        for(int i = 0; i < 5; i++)
        {
            if(numbers[i] != 0 && hash[numbers[i]] != 0)
            {
                return false;
            }
            else 
            {
                hash[numbers[i]] = 1;
            }
        }

        return true;
    }
};

4. Day10

4.1 最长回文子串(回文串)

  1. 题目链接: OR26 最长回文子串
  2. 题目描述:

  1. 解法:
    • 算法思路:枚举所有的中心点,然后向两边扩散。
  2. C++ 算法代码:
class Solution {
public:

    int getLongestPalindrome(string A) 
    {
        int n = A.size();

        int ret = 1;
        for(int i = 0; i < n; i++)
        {
            // 当⻓度是奇数的时候
            int left = i - 1;
            int right = i + 1;
            while(left >= 0 && right < n && A[left] == A[right])
            {
                left--;
                right++;
            }

            ret = max(ret, right - left - 1);

            // 当⻓度是偶数的时候
            left = i;
            right = i + 1;
            while(left >= 0 && right < n && A[left] == A[right])
            {
                left--;
                right++;
            }

            ret = max(ret, right - left - 1);
        }

        return ret;
    }
};

4.2 买卖股票的最好时机(一)(贪心)

  1. 题目链接: DP30 买卖股票的最好时机(一)
  2. 题目描述:

  1. 解法:
    • 算法思路:小贪心:
      • 因为只能买卖⼀次,因此,对于第 i 天来说,如果在这天选择卖出股票,应该在 [0, i] 天之内,股票最低点买入股票,此时就可以获得最大利润。
      • 那么,我们仅需维护⼀个前驱最小值的变量,并且不断更新结果即可。
  2. C++ 算法代码:
#include <iostream>
using namespace std;

const int N = 1e5 + 10;

int main() 
{
    int n = 0;
    cin >> n;

    int prices[N];
    for(int i = 0; i < n; i++)
    {
        cin >> prices[i];
    }

    int ret = 0;
    int premin = prices[0];
    for(int i = 1; i < n; i++)
    {
        premin = min(prices[i], premin);
        ret = max(ret, prices[i] - premin);
    }
    
    cout << ret << endl;

    return 0;
}

4.3 过河卒(动态规划 - 路径问题)

  1. 题目链接: DP13 [NOIP2002 普及组] 过河卒
  2. 题目描述:

  1. 解法:
    • 算法思路:简单路径 dp 问题:相当于是有障碍物的路径类问题,标记走到障碍物上的方法数为 0 即可。
  2. C++ 算法代码:
#include <iostream>
#include <vector>
using namespace std;

int abs(int a)
{
    if(a < 0)
    {
        return -a;
    }

    return a;
}

int main() 
{
    int n, m, x, y;
    cin >> n >> m >> x >> y;
    vector<vector<long long>> dp(n + 2, vector<long long>(m + 2));
    x += 1;
    y += 1;

    dp[0][1] = 1;
    for(int i = 1; i <= n + 1; i++)
    {
        for(int j = 1; j <= m + 1; j++)
        {
            if(i != x && j != y && abs(i - x) + abs(j - y) == 3 || (i == x && j == y))
            {
                dp[i][j] = 0;
            }
            else 
            {
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
            }
        }
    }
    
    cout << dp[n + 1][m + 1] << endl;

    return 0;
}

5. Day11

5.1 游游的水果大礼包(枚举)

  1. 题目链接: 游游的水果大礼包
  2. 题目描述:

  1. 解法:
    • 算法思路:
      • 很容易想到贪心,但是很不幸,贪心是错的。
      • 正确的解法应该是枚举所有的情况~
  2. C++ 算法代码:
#include <iostream>
using namespace std;

int main()
{
    int n, m, a, b;
    cin >> n >> m >> a >> b;
    
    long long ret = 0;
    for(long long i = 0; i <= min(n / 2, m); i++)
    {
        long long j = min(n - i * 2, (m - i) / 2);
        ret = max(ret, a * i + b * j);
    }
    
    cout << ret << endl;
    
    return 0;
}

5.2 买卖股票的最好时机(二)(贪心)

  1. 题目链接: DP31 买卖股票的最好时机(二)
  2. 题目描述:

  1. 解法:
    • 算法思路:小贪心:因为可以无限次交易,因此,只要股票的价格有上升,就统统把利润拿到⼿。
  2. C++ 算法代码:
#include <iostream>
using namespace std;

const int N = 1e5 + 10;

int main() 
{
    int n = 0;
    cin >> n;
    int prices[N] = {0};
    for(int i = 0; i < n; i++)
    {
        cin >> prices[i];
    }

    int ret = 0;
    for(int i = 0; i < n - 1; i++)
    {
        if(prices[i + 1] > prices[i])
        {
            ret += prices[i + 1] - prices[i];
        }
    }

    cout << ret << endl;

    return 0;
}

// 动态规划
#include <iostream>
#include <vector>
using namespace std;

const int N = 1e5 + 10;

int main() 
{
    int n = 0;
    cin >> n;
    int prices[N] = {0};
    for(int i = 0; i < n; i++)
    {
        cin >> prices[i];
    }

    vector<int> f(n + 1);   //卖出股票,没有股票什么都不干
    vector<int> g(n + 1);   //买入股票
    g[0] = -prices[0];

    for(int i = 1; i <= n; i++)
    {
        f[i] = max(f[i - 1], g[i - 1] + prices[i]);
        g[i] = max(g[i - 1], f[i - 1] - prices[i]);
    }

    cout << f[n] << endl;

    return 0;
}

5.3 倒置字符串(字符串)

  1. 题目链接: OR62 倒置字符串
  2. 题目描述:

  1. 解法:
    • 算法思路:找到规律反转字符串即可。
  2. C++ 算法代码:
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    string s;
    getline(cin, s);

    reverse(s.begin(), s.end());
    int left = 0;
    int right = 0;
    int n = s.size();
    while(right < n)
    {
        if(s[right] != ' ')
        {
            right++;
        }
        else
        {
            reverse(s.begin() + left, s.begin() + right);
            right++;
            left = right;
        }
    }

    reverse(s.begin() + left, s.begin() + right);

    cout << s << endl;

    return 0;
}

6. Day12

6.1 删除公共字符(哈希)

  1. 题目链接: OR63 删除公共字符
  2. 题目描述:

  1. 解法:
    • 算法思路:用哈希表记录⼀下字符串的字符信息即可。
  2. C++ 算法代码:
#include <iostream>
using namespace std;

int main() 
{
    string s, t;
    getline(cin, s);
    getline(cin, t);

    bool hash[300] = {0};
    for(auto& ch : t)
    {
        hash[ch] = true;
    }

    string ret;
    for(auto& ch : s)
    {
        if(!hash[ch])
        {
            ret += ch;
        }
    }

    cout << ret << endl;

    return 0;
}

6.2 两个链表的第⼀个公共结点(链表)

  1. 题目链接: JZ52 两个链表的第⼀个公共结点
  2. 题目描述:

  1. 解法:
    • 算法思路:根据两个链表走的路程相同,找到相交点。
  2. C++ 算法代码:
/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) 
	{
        ListNode* cur1 = pHead1;
		ListNode* cur2 = pHead2;

		while(cur1 != cur2)
		{
			cur1 = cur1 != nullptr ? cur1->next : pHead1;
			cur2 = cur2 != nullptr ? cur2->next : pHead2;
		}

		return cur1;
    }
};

6.3 mari和shiny(动态规划 - 线性dp)

  1. 题目链接: mari和shiny
  2. 题目描述:

  1. 解法:
    • 算法思路。简单线性 dp: 维护 i 位置之前,⼀共有多少个 “s” “sh” ,然后更新 “shy” 的个数。
  2. C++ 算法代码:
#include <iostream>
using namespace std;

int main()
{
    int n = 0;
    cin >> n;
    string str;
    cin >> str;
    
    long long s = 0;
    long long h = 0;
    long long y = 0;
    for(int i = 0; i < n; i++)
    {
        char ch = str[i];
        if(ch == 's')
        {
            s++;
        }
        else if(ch == 'h')
        {
            h += s;
        }
        else if(ch == 'y')
        {
            y += h;
        }
    }
    
    cout << y << endl;
    
    return 0;
}

相关文章:

  • 【运维笔记】docker 中 MySQL从5.7版本升级到8.0版本 - 平滑升级
  • C++学习之STL初识与容器
  • MuBlE:为机器人操作任务规划提供了逼真的视觉观察和精确的物理建模
  • 安卓免费工具:海量素材助力个性化头像制作
  • aardio - 虚表 —— 两个虚表之间互相拖动交换数据
  • WPS Word中英文混杂空格和行间距不一致调整方案
  • 牛客python蓝桥杯11-32(自用)
  • 无人机遥控器扩频技术解析!
  • 白盒测试(3):PCB阻抗测试方法
  • 设计模式 + java8方法引用 实现任意表的过滤器
  • Python----数据分析(Matplotlib五:pyplot的其他函数,Figure的其他函数, GridSpec)
  • Cursor + IDEA 双开极速交互
  • sysbench手动测试OceanBase v4.2.4集群
  • JmeterHttp请求头管理出现Unsupported Media Type问题解决
  • 第二次CCF-CSP认证(思路及源码)
  • 论述AI对学习发展的改变(网页设计)
  • Manus邀请码如何申请,有哪些办法
  • 【MySQL】表的增删查改(CRUD)(下)
  • 迷你世界脚本显示板管理接口:DisPlayBoard
  • vue项目使用svg
  • 不止是生态优势,“浙江绿谷”丽水有活力
  • 专家:炎症性肠病发病率上升,需加强疾病早期诊断
  • 上海蝉联全国中小企业发展环境评估综合排名第一
  • 习近平就乌拉圭前总统穆希卡逝世向乌拉圭总统奥尔西致唁电
  • 俄乌谈判开始
  • 政企共同发力:多地密集部署外贸企业抢抓90天政策窗口期