目录
- 1.孩子们的游戏
- 1.题目链接
- 2.算法原理详解 && 代码实现
- 2.大数加法
- 1.题目链接
- 2.算法原理详解 && 代码实现
- 3.拼三角
- 1.题目链接
- 2.算法原理详解 && 代码实现
1.孩子们的游戏
1.题目链接
- 孩子们的游戏
2.算法原理详解 && 代码实现
-
问题抽象:实际就是约瑟夫环问题
-
自己的版本:模拟 --> 环形链表/数组
int LastRemaining_Solution(int n, int m) { int cnt = n, time = 0; vector<bool> children(n, false); for(int i = 0; cnt != 1; i++) { if(!children[i % n] && time == m - 1) { children[i % n] = true; cnt--; time = 0; } if(!children[i % n]) { time++; } } for(int i = 0; i < n; i++) { if(!children[i]) { return i; } } return -1; }
-
优化版本:动态规划 + 空间优化 --> 个人感觉比较抽象:(
- 分析:每划去一个人,下一个人其实和本次划去的人有映射关系
- 状态表示:
dp[i]
:当有i
个孩子围成一圈时,最终获胜的孩子的编号是多少 - 状态转移方程:
dp[i] = (dp[i - 1] + m) % i
int LastRemaining_Solution(int n, int m) { int dp = 0; for(int i = 2; i <= n; i++) { dp = (dp + m) % i; } return dp; }
2.大数加法
1.题目链接
- 大数加法
2.算法原理详解 && 代码实现
- 自己的版本:无进位相加
string solve(string s, string t) { if(s.empty() && t.empty()) { return "0"; } int n = s.size(), m = t.size(); // 逆序字符串,便于运算 reverse(s.begin(), s.end()); reverse(t.begin(), t.end()); // 处理0,使两字符串位数一样 if(n > m) { for(int i = 0; i < n - m; i++) { t.push_back('0'); } } else if(n < m) { for(int i = 0; i < m - n; i++) { s.push_back('0'); } } // 无进位加法 int len = s.size(); vector<int> tmp(len, 0); for(int i = 0; i < len; i++) { tmp[i] = (s[i] - '0' + t[i] - '0'); } // 进位 string ret; int cur = 0, carry = 0; while(cur < len || carry) { if(cur < len) { carry += tmp[cur++]; } ret += carry % 10 + '0'; carry /= 10; } reverse(ret.begin(), ret.end()); return ret; }
- 优化版本:模拟竖式运算,相较于自己的版本简化了计算
string solve(string s, string t) { string ret; int i = s.size() - 1, j = t.size() - 1; int carry = 0; while(i >= 0 || j >= 0 || carry) { if(i >= 0) { carry += s[i--] - '0'; } if(j >= 0) { carry += t[j--] - '0'; } ret += carry % 10 + '0'; carry /= 10; } reverse(ret.begin(), ret.end()); return ret; }
3.拼三角
1.题目链接
- 拼三角
2.算法原理详解 && 代码实现
-
自己的思路:暴搜 --> DFS + 枚举
-
优化思路:排序 + 单调性枚举
#include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { int n = 0; cin >> n; vector<int> nums(6, 0); while(n--) { for(int i = 0; i < 6; i++) { cin >> nums[i]; } sort(nums.begin(), nums.end()); if(nums[0] + nums[1] > nums[2] && nums[3] + nums[4] > nums[5] || nums[0] + nums[2] > nums[3] && nums[1] + nums[4] > nums[5] || nums[0] + nums[3] > nums[4] && nums[1] + nums[2] > nums[5] || nums[0] + nums[4] > nums[5] && nums[1] + nums[2] > nums[3]) { cout << "Yes" << endl; } else { cout << "No" << endl; } } return 0; }