模拟题刷题2

目录

总结

[415. 字符串相加](#415. 字符串相加)

[43. 字符串相乘](#43. 字符串相乘)

[2549. 统计桌面上的不同数字](#2549. 统计桌面上的不同数字)

[3507. 移除最小数对使数组有序 I](#3507. 移除最小数对使数组有序 I)

[3175. 找到连续赢 K 场比赛的第一位玩家](#3175. 找到连续赢 K 场比赛的第一位玩家)

[537. 复数乘法](#537. 复数乘法)

[2352. 相等行列对](#2352. 相等行列对)

[2177. 找到和为给定整数的三个连续整数](#2177. 找到和为给定整数的三个连续整数)

[3354. 使数组元素等于零](#3354. 使数组元素等于零)

[999. 可以被一步捕获的棋子数](#999. 可以被一步捕获的棋子数)

CF282A

CF158A

CF263A

CF112A


总结

字符串高精度

删除元素: nums.erase(nums.begin()+index+1);

双指针比较

find函数查找int index=s.find('+');

stoi可转化符号

pair函数pair<int,int> 返回return {a,b}; 接收auto [a,b]=

哈希表string存数字带间隔

前缀和模拟

方向数组搜索信息

函数改字母大小写c = tolower((unsigned char)c);

415. 字符串相加

字符串模拟高精度加法

cpp 复制代码
class Solution {
public:
    string addStrings(string num1, string num2) {
        int i = num1.size() - 1;
        int j = num2.size() - 1;
        int carry = 0;
        string ans = "";
        while (i >= 0 && j >= 0) {
            int res = (num1[i--] - '0') + (num2[j--] - '0') + carry;
            carry = res / 10;
            res %= 10;
            ans = to_string(res) + ans;
        }
        while (i >= 0) {
            int res = num1[i--] - '0' + carry;
            carry = res / 10;
            res %= 10;
            ans = to_string(res) + ans;
        }
        while (j >= 0) {
            int res = num2[j--] - '0' + carry;
            carry = res / 10;
            res %= 10;
            ans = to_string(res) + ans;
        }
        if(carry){
            ans=to_string(carry)+ans;
        }
        return ans;
    }
};

43. 字符串相乘

法一:借助上一题的加法

cpp 复制代码
class Solution {
    string ans = "0";
    void add(string& t) {
        string res = "";
        int i = ans.size() - 1;
        int j = t.size() - 1;
        int carry = 0;
        while (i >= 0 && j >= 0) {
            int n = (ans[i--] - '0') + (t[j--] - '0') + carry;
            carry = n / 10;
            n %= 10;
            res = to_string(n) + res;
        }
        while (i >= 0) {
            int n = (ans[i--] - '0') + carry;
            carry = n / 10;
            n %= 10;
            res = to_string(n) + res;
        }
        while (j >= 0) {
            int n = (t[j--] - '0') + carry;
            carry = n / 10;
            n %= 10;
            res = to_string(n) + res;
        }
        if(carry)res=to_string(carry)+res;
        ans=res;
    }
public:
    string multiply(string num1, string num2) {
        if(num1=="0"||num2=="0")return "0";
        for (int i = num2.size() - 1; i >= 0; i--) {
            string t = "";
            int carry = 0;
            for (int j = num1.size()-1; j >= 0; j--) {
                int n = (num2[i] - '0') * (num1[j] - '0') + carry;
                carry = n / 10;
                n %= 10;
                t = to_string(n) + t;
            }
            if(carry)t=to_string(carry)+t;
            int k = num2.size() - i-1;
            while (k--)
                t += '0';
            add(t);
        }
        return ans;
    }
};

法二:创建 vector<int> res(n1+n2, 0),把每对位乘好累加到对应位置,最后把 vector 转为字符串并去掉前导零

cpp 复制代码
class Solution {
public:
    string multiply(string num1, string num2) {
        if (num1 == "0" || num2 == "0") return "0";
        int n1 = num1.size(), n2 = num2.size();
        vector<int> res(n1 + n2, 0);

        // 从低位到高位乘并加到 res 的适当位置
        for (int i = n1 - 1; i >= 0; --i) {
            int a = num1[i] - '0';
            for (int j = n2 - 1; j >= 0; --j) {
                int b = num2[j] - '0';
                int mul = a * b;
                int p1 = i + j;     // 高位索引
                int p2 = i + j + 1; // 低位索引
                int sum = mul + res[p2];
                res[p2] = sum % 10;
                res[p1] += sum / 10;
            }
        }

        // 转为字符串并去掉前导0
        string ans;
        int i = 0;
        while (i < (int)res.size() && res[i] == 0) ++i;
        for (; i < (int)res.size(); ++i) ans.push_back('0' + res[i]);
        return ans.empty() ? "0" : ans;
    }
};

2549. 统计桌面上的不同数字

简单的思维题

cpp 复制代码
class Solution {
public:
    int distinctIntegers(int n) {
        if(n==1)return 1;
        return n-1;
    }
};

3507. 移除最小数对使数组有序 I

删除元素: nums.erase(nums.begin()+index+1);

cpp 复制代码
class Solution {
public:
    int minimumPairRemoval(vector<int>& nums) {
        int ans=0;
        while(nums.size()>1){
            bool flag=true;
            int minsum=INT_MAX;
            int index=-1;
            for(int i=0;i<nums.size()-1;i++){
                int sum=nums[i]+nums[i+1];
                if(nums[i]>nums[i+1])flag=false;
                if(sum<minsum){
                    minsum=sum;
                    index=i;
                }
            }
            if(flag)break;
            ans++;
            nums[index]=minsum;
            nums.erase(nums.begin()+index+1);
        }
        return ans;
    }
};

3175. 找到连续赢 K 场比赛的第一位玩家

暴力超时

cpp 复制代码
class Solution {
public:
    int findWinningPlayer(vector<int>& skills, int k) {
        vector<vector<int>> s(skills.size(), vector<int>(3));
        for (int i = 0; i < skills.size(); i++) {
            s[i][0] = skills[i];
            s[i][1] = i;
            s[i][2] = 0;
        }
        int p = -1;
        while (p == -1) {
            if (s[0][0] > s[1][0]) {
                s[0][2]++;
                s[1][1] = 0;
                if (s[0][2] == k)p = s[0][1];
                s.push_back({s[1][0], s[1][1], s[1][2]});
                s.erase(s.begin() + 1);
            } else {
                s[1][2]++;
                s[0][1] = 0;
                if (s[1][2] == k)p = s[1][1];
                s.push_back({s[0][0], s[0][1], s[0][2]});
                s.erase(s.begin());
            }
        }
        return p;
    }
};

优化:双指针维护擂主和连胜

cpp 复制代码
class Solution {
public:
    int findWinningPlayer(vector<int>& skills, int k) {
        int champ=0;
        int win=0;
        for(int i=1;i<skills.size();i++){
            if(skills[champ]>skills[i]){
                win++;
            }
            else {
                win=1;
                champ=i;
            }
            if(win==k)return champ;
        }
        return champ;
    }
};

537. 复数乘法

有点繁琐,但是清晰易懂

cpp 复制代码
class Solution {
public:
    string complexNumberMultiply(string num1, string num2) {
        int n11 = 0;
        int n12 = 0;
        int n21 = 0;
        int n22 = 0;
        string n = "";
        int i = 0;
        for (i = 0; i < num1.size(); i++) {
            if (num1[i] == '+')
                break;
            n += num1[i];
        }
        n11 = stoi(n);
        n = "";
        for (int j = i + 1; j < num1.size(); j++) {
            if (num1[j] >= '0' && num1[j] <= '9')
                n += num1[j];
        }
        n12 = stoi(n);
        if (num1[i + 1] == '-')
            n12 = -n12;
        n = "";
        for (i = 0; i < num2.size(); i++) {
            if (num2[i] == '+')
                break;
            n += num2[i];
        }
        n21 = stoi(n);
        n = "";
        for (int j = i + 1; j < num2.size(); j++) {
            if (num2[j] >= '0' && num2[j] <= '9')
                n += num2[j];
        }
        n22 = stoi(n);
        if (num2[i + 1] == '-')
            n22 = -n22;
        int ans1 = n11 * n21 - n12 * n22;
        int ans2 = n11 * n22 + n12 * n21;
        string ans = "";
        if (ans1 < 0) ans+='-';
        ans += to_string(abs(ans1));
        ans += '+';
        if (ans2 < 0) ans+='-';
        ans += to_string(abs(ans2));
        ans+='i';
        return ans;
    }
};

实际上stoi本身就能解析带符号的字符串,不用判断负号

查找+可以用find函数返回下标

优化:

cpp 复制代码
class Solution {
    pair<int,int> parse(string& s){
        int index=s.find('+');
        int a=stoi(s.substr(0,index));
        int b=stoi(s.substr(index+1,s.size()-index-2));
        return {a,b};
    }
public:
    string complexNumberMultiply(string num1, string num2) {
        auto [a,b]=parse(num1);
        auto [c,d]=parse(num2);
        int real=a*c-b*d;
        int image=a*d+b*c;
        return to_string(real)+'+'+to_string(image)+'i';
    }
};

2352. 相等行列对

哈希表存储重复行/列,注意用string存储数字时,要在两数中间加个符号避免特殊情况,例如:

\[11,1\],\[1,11\]\],存储时若不加间隔符号,就都是"111" ```cpp class Solution { public: int equalPairs(vector>& grid) { unordered_mapmapR; unordered_mapmapC; for(int i=0;i sumOfThree(long long num) { if((num/3)*3==num)return {num/3-1,num/3,num/3+1}; else return {}; } }; ``` ## [3354. 使数组元素等于零](https://leetcode.cn/problems/make-array-elements-equal-to-zero/ "3354. 使数组元素等于零") 前缀和模拟 打砖块。若初始方向向右,则应保证左右两边砖块相等或右边比左边多1。若初始方向向左,则应保证左右两边砖块相等或左边比右边多1。 所以,ans在左右相等时+2,在左右差1时+1 可以先用sum统计总砖块 ```cpp class Solution { public: int countValidSelections(vector& nums) { int ans=0; int sum=0; int pre=0; for(int t:nums)sum+=t; for(int t:nums){ if(t)pre+=t; else { if(pre*2==sum)ans+=2; else if(abs(sum-pre*2)==1)ans++; } } return ans; } }; ``` ## [999. 可以被一步捕获的棋子数](https://leetcode.cn/problems/available-captures-for-rook/ "999. 可以被一步捕获的棋子数") 纯模拟 ```cpp class Solution { public: int numRookCaptures(vector>& board) { int ans=0; int x,y; int q=1; for(int i=0;i=0){ if(board[x][t]=='p'){ ans++; break; } else if(board[x][t]=='B'){ break; } else t--; } t=y; while(t=0){ if(board[t][y]=='p'){ ans++; break; } else if(board[t][y]=='B'){ break; } else t--; } t=x; while(t>& board) { int x=-1; int y=-1; int n=board.size(); for(int i=0;i=0&&ny>=0&&nx> n; while (n--) { cin >> t; if (t[1] == '+') x++; else x--; } cout << x; } ``` ## CF158A 想复杂了,只要两次for一次读入一次判断即可 ```cpp void solve() { int n, k; cin >> n >> k; vector s(n); for (int i = 0; i < n; i++) { cin >> s[i]; } int ans = 0; int p = s[k - 1]; for (int i = 0; i < n; i++) { if (s[i] >= p && s[i]) { ans++; } } cout << ans; } ``` ## CF263A ```cpp void solve() { int x, y; vector> gra(5, vector(5)); for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { cin >> gra[i][j]; if (gra[i][j]) { x = i; y = j; } } } cout << abs(2 - x) + abs(2 - y); } ``` ## CF112A ```cpp void solve() { string a, b; cin >> a >> b; for (int i = 0; i < a.size(); i++) { if (a[i] >= 'A' && a[i] <= 'Z') { a[i] = a[i] - 'A' + 'a'; } if (b[i] >= 'A' && b[i] <= 'Z') { b[i] = b[i] - 'A' + 'a'; } if (a[i] > b[i]) { cout << 1; return; } else if (a[i] < b[i]) { cout << -1; return; } } cout << 0; } ``` 这是手动改大小和比较,优化版是调用函数 ```cpp void solve() { string a, b; cin >> a >> b; for (int i = 0; i < (int)a.size(); ++i) { char ca = tolower((unsigned char)a[i]); char cb = tolower((unsigned char)b[i]); if (ca > cb) { cout << 1; return; } if (ca < cb) { cout << -1; return; } } cout << 0; } ``` 或者 ```cpp void solve() { string a, b; cin >> a >> b; for (char& c : a) c = tolower((unsigned char)c); for (char& c : b) c = tolower((unsigned char)c); if (a > b) cout << 1; else if (a < b) cout << -1; else cout << 0; } ``` ![](https://i-blog.csdnimg.cn/direct/e396ceae33714304b3874036593d7d1f.gif)

相关推荐
AI 菌2 小时前
DeepSeek-OCR 解读
人工智能·算法·计算机视觉·大模型·ocr
历程里程碑2 小时前
Linux 5 目录权限与粘滞位详解
linux·运维·服务器·数据结构·python·算法·tornado
yi.Ist2 小时前
关于若干基础的几何问题
c++·学习·算法·计算几何
毅炼2 小时前
Netty 常见问题总结
java·网络·数据结构·算法·哈希算法
Anastasiozzzz2 小时前
leetcodehot100--最小栈 MinStack
java·javascript·算法
历程里程碑2 小时前
双指针2--盛水最多的容器
大数据·数据结构·算法·leetcode·elasticsearch·搜索引擎·散列表
hetao17338373 小时前
2026-01-22~23 hetao1733837 的刷题笔记
c++·笔记·算法
风筝在晴天搁浅3 小时前
hot100 230.二叉搜索树中第K小的元素
数据结构·算法
June bug3 小时前
(#数组/链表操作)寻找两个正序数组的中位数
数据结构·python·算法·leetcode·面试·职场和发展·跳槽