11111

// 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值