// Problem P01. [算法课分治] 最大二叉树
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> a;
void ans(int l, int r){
if(l == r){
cout << "null" << ' ';
return;
}
int maxa = INT_MIN;
int maxi;
for (int i = l; i < r; i++) {
if (a[i] > maxa) {
maxa = a[i];
maxi = i;
}
}
cout << maxa << ' ';
if (l < maxi || maxi+1 < r) {
ans(l, maxi);
ans(maxi+1, r);
}
}
int main()
{
int n, len = 0;
char b;
while(cin >> n){
a.push_back(n);
len++;
if((b = getchar()) == '\n'){
break;
}
}
ans(0, len);
}
//Problem P02. [算法课分治] 寻找多数
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int a[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int cnt = 1;
int res = a[0];
for (int i = 1; i < n; i++) {
if (a[i] == res) {
cnt++;
} else {
cnt--;
if (cnt == 0) {
res = a[i+1];
}
}
}
cout << res;
}
//Problem P03. [算法课分治] 找到最大子序和
#include <iostream>
using namespace std;
int main(){
int n;
cin >> n;
int a[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int res, dp[n];
dp[0] = a[0];
res = dp[0];
for (int i = 1; i < n; i++) {
dp[i] = max(dp[i - 1] + a[i], a[i]);
res = max(dp[i], res);
}
cout << res;
}
//Problem P04. [算法课分治] 找到 k 个最小数
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int n, k;
cin >> n >> k;
int a[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a+n);
for (int i = 0; i < k; i++) {
cout << a[i] << " ";
}
}
//Problem P05. [算法课分治] 寻找第 k 个最大元素
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int n, k;
cin >> n >> k;
int a[n], b[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a+n, greater<int>());
cout << a[k-1];
}
// Problem P06. [算法课动态规划] 换硬币
#include <iostream>
using namespace std;
int main() {
int n;
int coins[] = {2, 5, 7};
cin >> n;
int Min[100];
for (int k = 1; k < 100; k++) {
Min[k] = INT_MAX;
}
Min[0] = 0;
for (int j = 0; j < 3; j++) {
for (int i = coins[j]; i <= n; i++) {
if (Min[i - coins[j]] != INT_MAX)
Min[i] = min(Min[i], Min[i - coins[j]] + 1);
}
}
if (Min[n] == INT_MAX) {
cout << "-1" << endl;
} else {
cout << Min[n] << endl;
}
return 0;
}
// Problem P07. [算法课动态规划]走网格
#include <iostream>
#include <vector>
using namespace std;
vector<int> H;
int main() {
int m, n;
cin >> m >> n;
int dp[m][n];
for (int i = 0; i < m; i++){
dp[i][0] = 1;
}
for (int j = 0; j < n; j++) {
dp[0][j] = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
cout << dp[m-1][n-1];
}
//Problem P08. [算法课动态规划]爬楼梯
#include <iostream>
using namespace std;
int fib(int n) {
if (n == 1)
return 1;
if (n == 2)
return 2;
if (n > 2){
return fib(n-1) + fib(n - 2);
}
}
int main() {
int n;
cin >> n;
cout << fib(n);
}
// Problem P09. [算法课动态规划]背包问题
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=505;
long long ans[maxn][maxn],w[maxn],v[maxn];
int main(){
long long n,c;
cin >> n >> c;
for(int i = 1;i <= n;++ i){
cin >> w[i];
}
for(int i = 1;i <= n;++ i){
cin >> v[i];
}
for(int i=1;i<=n;++i){
for(int j = 1;j <= c;++ j){
if(j >= w[i]){
ans[i][j] = max(ans[i-1][j-w[i]]+v[i],ans[i-1][j]);
}else
ans[i][j] = ans[i-1][j];
}
}
cout << ans[n][c];
return 0;
}
// Problem P10. [算法课动态规划]最长回文子串
#include<iostream>
#include<vector>
#include<string>
using namespace std;
bool valid(string s, int l, int r) {
while(l < r) {
if (s[l] != s[r]) {
return false;
}
l++;
r--;
}
return true;
}
int main(){
string s;
cin >> s;
int len = s.size();
if (len < 2) {
cout << s;
}
int maxlen = 1;
string res = s.substr(0,1);
for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j < len; j++) {
if (j - i + 1 > maxlen && valid(s, i, j)) {
maxlen = j - i + 1;
res = s.substr(i, maxlen);
}
}
}
cout << res;
}
// Problem P11. [算法课动态规划]连续数组最大和
#include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
int a[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int dp[n];
dp[0] = a[0];
int res = dp[0];
for (int i = 1; i < n; i++) {
dp[i] = max(dp[i - 1] + a[i], a[i]);
if (dp[i] > res) {
res = dp[i];
}
}
cout << res << endl;
}
// Problem P12. [算法课贪婪]分发饼干
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int ans(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int index = s.size() - 1; // 饼干数组的下标
int result = 0;
for (int i = g.size() - 1; i >= 0; i--) { // 遍历胃口
if (index >= 0 && s[index] >= g[i]) { // 遍历饼干
result++;
index--;
}
}
return result;
}
int main()
{
vector<int> child;
vector<int> cookie;
int n = 0;
while (cin >> n) {
child.push_back(n);
if(getchar() == '\n') break;
}
while (cin >> n) {
cookie.push_back(n);
if(getchar() == '\n') break;
}
cout << ans(child, cookie);
}
//Problem P13. [算法课贪婪]6和9组成的最大数字
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
if(n > 999) {
if (n/1000 != 9) {
cout << n + 3000;
} else if ((n - 9000) / 100 != 9) {
cout << n + 300;
} else if ((n - 9900) / 10 != 9) {
cout << n + 30;
} else if ((n - 9990) / 10 != 9 || n == 9999 ){
cout << 9999;
}
} else if (n > 99 & n <= 999) {
if (n/100 != 9) {
cout << n + 300;
} else if ((n - 900) / 10 != 9) {
cout << n + 30;
} else if ((n - 990) / 10 != 9 || n == 999) {
cout << 999;
}
} else if (n > 9 & n <= 99) {
if (n/10 != 9) {
cout << n + 30;
} else if ((n - 90) / 10 != 9 || n == 99){
cout << 99;
}
} else if (n == 6|| n == 9){
cout << 9;
}
}
// Problem P14. [算法课贪婪]盛最多的水
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> H;
int main() {
int h;
while(cin >> h) {
H.push_back(h);
}
int l = 0, r = H.size() - 1, maxV = 0;
while(l < r) {
int curV = min(H[l], H[r]) * (r - l);
maxV = max(maxV, curV);
if (H[l] > H[r]) {
r--;
} else {
l++;
}
}
cout << maxV;
}
// Problem P15. [算法课回溯]括号生成
#include <iostream>
#include <vector>
using namespace std;
vector<string> strs;
void dfs(int l, int r, string curstr) {
if (l == 0 && r == 0) {
strs.push_back(curstr);
return;
}
if (l <= r && l >=0) {
dfs(l-1, r, curstr + "(");
dfs(l, r-1, curstr + ")");
}
}
int main() {
int n;
cin >> n;
dfs(n, n, "");
cout << "[";
for (int i = 0; i < strs.size()-1; i++) {
cout << strs[i] << ", ";
}
cout << strs[strs.size()-1];
cout << "]";
}
// Problem P16. [算法课回溯]组合问题
#include <iostream>
#include <vector>
using namespace std;
void backtracking(vector<vector<int>> & result, vector<int> & path, int n, int k, int startIndex) {
if (path.size() == k) {
result.push_back(path);
return;
}
for (int i = startIndex; i <= n; i++) {
path.push_back(i);
backtracking(result, path, n, k, i + 1);
path.pop_back();
}
}
int main() {
int n, k;
cin >> n >> k;
vector<vector<int>> result;
vector<int> path;
backtracking(result, path, n, k, 1);
cout << "[";
for (int i = 0; i < result.size(); i++) {
cout << "[";
for (int j = 0; j < result[i].size(); j++) {
cout << result[i][j];
if(j < result[i].size() - 1) {
cout << ", ";
}
}
cout << "]";
if (i < result.size() - 1) {
cout << ", ";
}
}
cout << "]";
}
// Problem P17. [算法课回溯]找出所有子集的异或总和再求和
#include <iostream>
#include <vector>
using namespace std;
int ans(vector<int>& nums) {
int bits = 0;
for (int i = 0; i < nums.size(); ++i) {
bits |= nums[i];
}
return bits << (nums.size() - 1);
}
int main() {
vector<int> nums;
int n = 0;
while (cin >> n) {
nums.push_back(n);
if (getchar() == '\n') break;
}
int res = ans(nums);
cout << res << endl;
}
// Problem P18. [算法课回溯]分割回文串
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
bool isPalindrome(const string& s, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
if (s[i] != s[j]) {
return false;
}
}
return true;
}
void backtracking(const string& s, int startIndex, vector<vector<string>>& result, vector<string>& path) {
if (startIndex >= s.size()) {
result.push_back(path);
return;
}
for (int i = startIndex; i < s.size(); i++) {
if (isPalindrome(s, startIndex, i)) {
string str = s.substr(startIndex, i - startIndex + 1);
path.push_back(str);
backtracking(s, i + 1, result, path);
path.pop_back();
}
}
}
int main() {
string input;
cin >> input;
vector<vector<string>> result;
vector<string> path;
backtracking(input, 0, result, path);
sort(result.begin(), result.end());
cout << "[";
for (int i = 0; i < result.size(); ++i) {
cout << "[";
for (int j = 0; j < result[i].size(); ++j) {
cout << result[i][j];
if (j < result[i].size() - 1) {
cout << ", ";
}
}
cout << "]";
if (i < result.size() - 1) {
cout << ", ";
}
}
cout << "]" << endl;
}
// Problem P19. [算法课回溯]目标和
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int findTargetSumWays(vector<int>& nums, int S) {
int sum = accumulate(nums.begin(), nums.end(), 0);
if (S > sum) return 0; // 此时没有方案
if ((S + sum) % 2 == 1) return 0; // 此时没有方案
int bagSize = (S + sum) / 2;
vector<int> dp(bagSize + 1, 0);
dp[0] = 1;
for (int i = 0; i < nums.size(); i++) {
for (int j = bagSize; j >= nums[i]; j--) {
dp[j] += dp[j - nums[i]];
}
}
return dp[bagSize];
}
int main() {
vector<int> nums;
int num;
while (cin >> num) {
nums.push_back(num);
// 检查是否有更多输入
if (cin.get() == '\n') break;
}
int target;
cin >> target;
int result = findTargetSumWays(nums, target);
cout << result << endl;
}
// Problem P20. [算法课回溯] 电话号码的字母组合
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void backtracking(const string& digits, int index, const string letterMap[], string& currentCombination, vector<string>& result) {
if (index == digits.size()) {
result.push_back(currentCombination);
return;
}
int digit = digits[index] - '0'; // 将当前索引处的数字转换为整数
const string& letters = letterMap[digit]; // 获取数字对应的字母序列
// 遍历该数字对应的字母
for (size_t i = 0; i < letters.size(); ++i) {
currentCombination.push_back(letters[i]); // 加入当前字母
backtracking(digits, index + 1, letterMap, currentCombination, result); // 递归处理下一个数字
currentCombination.pop_back(); // 移除最后一个加入的字母,准备尝试下一个字母
}
}
vector<string> letterCombinations(const string& digits, const string letterMap[]) {
vector<string> result;
string currentCombination;
if (digits.empty()) {
return result;
}
backtracking(digits, 0, letterMap, currentCombination, result); // 从第一个数字开始构建组合
return result;
}
int main() {
const string letterMap[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz" // 9
};
string input;
cin >> input;
vector<string> combinations = letterCombinations(input, letterMap);
cout << "[";
bool first = true;
for (const auto& combination : combinations) {
if (!first) {
cout << ", ";
} else {
first = false;
}
cout << combination;
}
cout << "]" << endl;
return 0;
}
// Problem P21. [算法课回溯]优美的排列
#include <iostream>
#include <vector>
int cnt = 0;
using namespace std;
void backtrack(vector<bool>& used, int idx, int n)
{
if(idx > n)
{
cnt++;
return;
}
for(int i=1; i<n+1; i++)
{
if(used[i]==true && (i%idx==0 || idx%i==0))
{
used[i] = false;
backtrack(used, idx+1, n);
used[i] = true;
}
}
}
int main()
{
int n;
cin >> n;
vector<bool> used = vector<bool>(n+1, true);//bool容器装数字,表示用没用过
backtrack(used, 1, n);
cout << cnt;
return 0;
}
// Problem P22. [算法课分支限界法]组合
#include <iostream>
#include <vector>
using namespace std;
// 回溯函数
void backtracking(int n, int k, int startIndex, vector<vector<int>>& result, vector<int>& path) {
if (path.size() == k) {
result.push_back(path);
return;
}
for (int i = startIndex; i <= n; i++) {
path.push_back(i); // 处理节点
backtracking(n, k, i + 1, result, path); // 递归
path.pop_back(); // 回溯,撤销处理的节点
}
}
int main() {
int n, k;
cin >> n >> k;
vector<vector<int>> result; // 存放符合条件结果的集合
vector<int> path; // 用来存放符合条件结果
backtracking(n, k, 1, result, path);
// 使用传统 for 循环遍历 result
for (int i = 0; i < result.size(); i++) {
for (int j = 0; j < result[i].size(); j++) {
cout << result[i][j];
if (j < result[i].size() - 1) {
cout << " ";
}
}
cout << endl;
}
}
// Problem P23. [算法课分支限界法]大礼包
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int dfs(const vector<int>& price, const vector<vector<int>>& special, vector<int> needs) {
int cost = 0;
for (int i = 0; i < needs.size(); ++i) {
cost += price[i] * needs[i];
}
for (const auto& offer : special) {
bool valid = true;
for (int i = 0; i < needs.size(); ++i) {
if (offer[i] > needs[i]) {
valid = false;
break;
}
}
if (valid) {
vector<int> new_needs(needs);
for (int i = 0; i < needs.size(); ++i) {
new_needs[i] -= offer[i];
}
cost = min(cost, dfs(price, special, new_needs) + offer.back());
}
}
return cost;
}
int main() {
vector<int> price, needs;
vector<vector<int>> special;
int p;
while (cin >> p) {
price.push_back(p);
if (getchar() == '\n') break;
}
int n = price.back();
price.pop_back();
for (int i = 0; i < n; ++i) {
vector<int> offer;
while (cin >> p) {
offer.push_back(p);
if (getchar() == '\n') break;
}
special.push_back(offer);
}
while (cin >> p) {
needs.push_back(p);
if (getchar() == '\n') break;
}
cout << dfs(price, special, needs) << endl;
}
// Problem P24. [算法课分支限界法]Partition to K Equal Sum Subsets
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
// 回溯函数
bool backtrack(vector<int>& nums, int k, int idx, int cw, int target, vector<int>& help) {
if (k == 0) return true;
if (cw == target) return backtrack(nums, k - 1, 0, 0, target, help);
for (int i = idx; i < nums.size(); i++) {
if (help[i] == 0 && cw + nums[i] <= target) {
help[i] = 1;
if (backtrack(nums, k, i + 1, cw + nums[i], target, help)) return true;
help[i] = 0;
}
}
return false;
}
// 主函数,检查是否可以将 nums 分成 k 个和相等的子集
bool canPartitionKSubsets(vector<int>& nums, int k) {
int sum = accumulate(nums.begin(), nums.end(), 0);
if (sum % k != 0) return false;
int target = sum / k;
vector<int> help(nums.size(), 0);
return backtrack(nums, k, 0, 0, target, help);
}
int main() {
int k;
vector<int> nums;
int i;
while (cin >> i) {
nums.push_back(i);
if (cin.peek() == '\n') break;
}
cin >> k;
bool result = canPartitionKSubsets(nums, k);
if (result) {
cout << "true" << endl;
} else {
cout << "false" << endl;
}
}
// Problem P25. [算法课贪心] 跳跃游戏
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool canJump(vector<int>& nums) {
int maxReach = 0;
for (int i = 0; i < nums.size(); i++) {
if (i > maxReach) return false;
maxReach = max(maxReach, i + nums[i]);
}
return true;
}
int main() {
vector<int> nums;
int num;
while (cin >> num) {
nums.push_back(num);
}
bool result = canJump(nums);
if (result)
cout << "true" << endl;
else
cout << "false" << endl;
}
// Problem P26. [算法课动态规划] 整数拆分
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int integerBreak(int n) {
if (n < 4) { // 小于4,返回n-1
return n - 1;
}
vector<int> dp(n + 1, 0); // 动态规划数组
dp[2] = 1;
for (int i = 3; i <= n; i++) {
dp[i] = max(max(2 * (i - 2), 2 * dp[i - 2]), max(3 * (i - 3), 3 * dp[i - 3])); // 动态转移方程
}
return dp[n];
}
int main() {
int n;
cin >> n;
int result = integerBreak(n);
cout << result << endl;
}
// Problem P27. [算法课动态规划] 打家劫舍
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> nums;
int x;
while(cin >> x)
{
nums.push_back(x);
}
int n = nums.size();//有n间房子,每间房子有的钱储存在nums数组中
if(n == 1)//只有1间房子
{
cout << nums[0];
return 0;
}
int maxs[n];//定义有i间房子的话,房子编号从0开始,可以偷到最多的钱;
maxs[0] = nums[0];//第0间房子,偷到最多钱就第0间房子的钱数
maxs[1] = max(nums[0], nums[1]);//偷到第1间房子,则从第0间和第1间偷最多的
for(int i=2; i<n; i++)//从3间房子起步
{
maxs[i] = max(maxs[i-2]+nums[i], maxs[i-1]);
}
cout << maxs[n-1];//最后一间房子位置是n-1;
return 0;
}
// Problem P28. [算法课动态规划] 戳气球
#include <iostream>
#include <vector>
using namespace std;
int dp[305][305];//默认初始值为0
int main()
{
vector<int> nums;
int x;
while(cin >> x)
{
nums.push_back(x);
}
int n = nums.size();//有n个气球
nums.insert(nums.begin(), 1);//在数组前后插入个1;
nums.push_back(1);
for(int len=1; len<=n; len++)
{
for(int left=1; left<=n-len+1; left++)
{
int right = left+len-1;
for(int k=left; k<=right; k++)
{
dp[left][right] = max(dp[left][right], dp[left][k-1]+dp[k+1][right]+nums[left-1]*nums[k]*nums[right+1]);
}
}
}
cout << dp[1][n];
return 0;
}
// Problem P29. [算法课贪心] 分发糖果
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> ratings;
int x;
while(cin >> x)
{
ratings.push_back(x);
}
int n = ratings.size();//有n个气球
vector<int> candyVec(ratings.size(), 1);
// 从前向后
for (int i = 1; i < ratings.size(); i++) {
if (ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1;
}
// 从后向前
for (int i = ratings.size() - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1] ) {
candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);
}
}
// 统计结果
int result = 0;
for (int i = 0; i < candyVec.size(); i++) result += candyVec[i];
cout << result;
return 0;
}
// Problem P30. [算法课双指针] 三数之和
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++) {
if (nums[i] > 0) {
return result;
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 1; // 左指针
int right = nums.size() - 1; // 右指针
while (right > left) {
if (nums[i] + nums[left] + nums[right] > 0) right--; // 如果总和大于0,移动右指针
else if (nums[i] + nums[left] + nums[right] < 0) left++; // 如果总和小于0,移动左指针
else {
// 如果找到了一个三元组,添加到结果集中
result.push_back(vector<int>{nums[i], nums[left], nums[right]});
// 移动左右指针并去除重复元素
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
right--;
left++;
}
}
}
return result;
}
int main() {
int size;
cin >> size;
vector<int> nums(size);
for(int i = 0; i < size; ++i) {
cin >> nums[i];
}
vector<vector<int>> result = threeSum(nums);
cout << "["; //
for(size_t i = 0; i < result.size(); ++i) {
cout << "["; //
for(size_t j = 0; j < result[i].size(); ++j) {
cout << result[i][j];
if(j < result[i].size() - 1)
cout << ",";
}
cout << "]";
if(i < result.size() - 1)
cout << ",";
}
cout << "]" << endl;
return 0;
}
// Problem P31. [算法课栈] 反转括号
#include <iostream>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;
// 反转括号内的字符串
string reverseParentheses(string s) {
stack<string> stk; // 使用栈来存储中间结果
string str; // 当前正在构建的字符串
// 遍历输入字符串中的每个字符
for (int i = 0; i < s.length(); ++i) { // 使用传统for循环遍历字符串
char ch = s[i];
if (ch == '(') {
// 遇到开括号,将当前字符串压入栈,并清空当前字符串
stk.push(str);
str = "";
} else if (ch == ')') {
// 遇到闭括号,反转当前字符串,并与栈顶字符串拼接
reverse(str.begin(), str.end());
str = stk.top() + str;
stk.pop(); // 弹出栈顶的字符串
} else {
// 普通字符,直接添加到当前字符串末尾
str.push_back(ch);
}
}
return str; // 返回最终结果
}
int main() {
string input; // 输入字符串
getline(cin, input); // 从标准输入读取一行字符串
string result = reverseParentheses(input); // 调用reverseParentheses函数计算结果
cout << result << endl; // 输出结果
return 0; // 主函数结束
}
// Problem P32. [算法课贪心] 跳跃游戏
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
cin >> n;
int nums[n];
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
if (n == 1) return 0;
int curDistance = 0; // 当前覆盖最远距离下标
int ans = 0; // 记录走的最大步数
int nextDistance = 0; // 下一步覆盖最远距离下标
for (int i = 0; i < n; i++) {
nextDistance = max(nums[i] + i, nextDistance); // 更新下一步覆盖最远距离下标
if (i == curDistance) { // 遇到当前覆盖最远距离下标
ans++; // 需要走下一步
curDistance = nextDistance; // 更新当前覆盖最远距离下标(相当于加油了)
if (nextDistance >= n - 1) break; // 当前覆盖最远距到达集合终点,不用做ans++操作了,直接结束
}
}
cout << ans;
return 0;
}
//Problem P33. [算法课指针] 颜色分类
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
cin >> n;
int a[n], b[n];
for(int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a+n);
cout << "[";
for(int i = 0; i < n-1; i++) {
cout << a[i] << ",";
}
cout << a[n-1];
cout << "]";
}
// Problem P34. [算法课分治] 找假币
#include <iostream>
#include <algorithm>
using namespace std;
int ans(int a[], int l, int r) {
if (l >= r) {
return l;
}
int m = (l + r) / 2;
int left = ans(a, l, m);
int right = ans(a, m + 1, r);
return a[left] < a[right] ? left : right;
}
int main() {
int n; // 存储硬币的数量
cin >> n;
int a[n];
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
int pos = ans(a, 1, n);
cout << pos;
}
// Problem P35. [算法课贪婪] 最少操作使数组递增
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
cin >> n;
int a[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int ans = 0;
// i < n-1 !!!
for (int i = 0; i < n - 1; i++) {
while(a[i] >= a[i+1]){
a[i+1] += 1;
ans++;
}
}
cout << ans;
}
// Problem P36. [算法课回溯] 组合求和
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool compare(const vector<int>& a, const vector<int>& b) {
return a > b;
}
void backtracking(int targetSum, int k, int sum, int startIndex, vector<vector<int>>& result, vector<int>& path) {
if (path.size() == k) {
if (sum == targetSum) result.push_back(path);
return;
}
for (int i = startIndex; i <= 9; i++) {
sum += i;
path.push_back(i);
backtracking(targetSum, k, sum, i + 1, result, path); // 注意i+1
sum -= i;
path.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
vector<vector<int>> result;
vector<int> path;
backtracking(n, k, 0, 1, result, path);
return result;
}
int main() {
int k, n;
cin >> k >> n;
vector<vector<int>> result = combinationSum3(k, n);
// 按照字典序从大到小排序
sort(result.begin(), result.end(), compare);
if (result.empty()) {
cout << "0" << endl;
} else {
for (const auto& combination : result) {
for (int i = 0; i < combination.size(); ++i) {
cout << combination[i];
if (i < combination.size() - 1) {
cout << " ";
}
}
cout << endl;
}
}
return 0;
}
// Problem P37. [算法课动态规划] 完全平方数
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> dp(n + 1, INT_MAX);
dp[0] = 0;//dp[0]表示 和为0的完全平方数的最小数量
for (int i = 0; i <= n; i++) { // 遍历背包
for (int j = 1; j * j <= i; j++) { // 遍历物品
dp[i] = min(dp[i - j*j] + 1, dp[i]);
}
}
cout << dp[n];
return 0;
}
11111
最新推荐文章于 2026-06-21 17:05:31 发布

320

被折叠的 条评论
为什么被折叠?



