数字间加上加减乘,表达式结果等于某个数的所有可能
vector<string> addOperators(string num, int target) {
vector<string> ans;
search(num, target, 0, "", 0, 0, ans);
return ans;
}
void search(string num, int target, int idx, string lastExprStr,
long lastExprVal, long lastNum, vector<string> &ans) {
if (idx == num.size()) {
if (lastExprVal == target) ans.push_back(lastExprStr);
return;
}
// [idx..i]是currStr, [i+1..]进递归
for (int i = idx; i < num.size(); i++) {
if (i > idx && num[idx] == '0') continue; // 多位数不能以"0"开头
auto currStr = num.substr(idx, i - idx + 1);
long currNum = stol(currStr);
if (idx == 0) {
search(num, target, i + 1, currStr, currNum, currNum, ans);
} else {
search(num, target, i + 1, lastExprStr + "+" + currStr,
lastExprVal + currNum, currNum, ans);
search(num, target, i + 1, lastExprStr + "-" + currStr,
lastExprVal - currNum, -currNum, ans);
// 比如 lastExprVal=1+2+3,现在遇到*4,要lastExprVal-3+3*4
// 若再遇到*5,要lastExprVal-(3*4)+(3*4)*5
search(num, target, i + 1, lastExprStr + "*" + currStr,
lastExprVal - lastNum + lastNum * currNum, lastNum * currNum, ans);
}
}
}
联系:表达式加括号的方式数只需要分治
24点游戏
穷举:从nums[]中任取两个数,遍历四种运算符,对每种运算符生成 arr[其余操作数, 此次运算结果],在arr上递归。
bool judgePoint24(vector<int>& nums) {
vector<double> v(nums.begin(), nums.end());
return solve(v);
}
bool solve(vector<double>& nums) {
const vector<char> ops = {'+', '-', '*', '/'};
const int N = nums.size();
const double EPSILON = 1e-6;
if (N == 1) return abs(nums[0] - 24) < EPSILON;
// 任取两个数
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (i == j) continue;
// 先把剩下的数放入新数组
vector<double> arr;
for (int k = 0; k < N; k++) {
if (k != i && k != j) {
arr.push_back(nums[k]);
}
}
for (char op : ops) {
if ((op == '+' || op == '*') && i > j) continue; // +*满足交换律,减少重复计算
if (op == '/' && abs(nums[j]) < EPSILON) continue;
double ans;
if (op == '+') ans = nums[i] + nums[j];
else if (op == '-') ans = nums[i] - nums[j];
else if (op == '*') ans = nums[i] * nums[j];
else if (op == '/') ans = nums[i] / nums[j];
arr.push_back(ans);
if (solve(arr)) return true;
arr.pop_back();
}
}
}
return false;
}