题目
已知算式:1 口 2 口 3 口 4 口 5 口 6 口 7 口 8 口 9 = 110
要求在中间的 8 个空中填写+、 −,或不填,使得构成的表达式判断是不是
正确,正确则输出……
(如果空位中没有填写符号,则这几个数组成一个新的 N 位数,比如 1 口
2,可以是 1+2,也可以是 12)
思路
通过深搜直接暴力求解,本人只想到这种解法,如果有大佬有更好的解法欢迎评论。一共8个空每个空3中符号,共3^8=6561种情况。dfs显然足矣。
代码
// fileTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <fstream>
#include <vector>
#include <numeric>
#include <map>
#include <queue>
#include <string>
using namespace std;
vector<char> operate = { '*','+','-' };
vector<vector<char>> legal_operate;
// 思路2:将*替换成空字符,1+2*3*4-5+6*7*8*9-->1+234-5+6789进行字符串求值运算
// 0 1
int calculate(const std::string& s) {
int result = 0;
int num = 0; // 用于存储当前解析的数字
int sign = 1; // 1 表示加号,-1 表示减号
for (char c : s) {
if (isdigit(c)) {
num = num * 10 + (c - '0'); // 将当前数字字符转换为整数,并加到num上
}
else {
result += sign * num; // 在遇到符号前,先将之前的数字(如果有的话)加到结果中
num = 0; // 重置num,为解析下一个数字做准备
if (c == '+') sign = 1;
if (c == '-') sign = -1;
}
}
result += sign * num; // 不要忘了加上最后一个数字
return result;
}
pair<int,string> cal2(vector<char> oper) {
string ss = "";
vector<int> num = { 1,2,3,4,5,6,7,8,9 };
for (int i = 0; i < oper.size(); i++) {
if (oper[i] == '*')
ss += to_string(num[i]);
else {
ss += to_string(num[i]) + oper[i];
}
}
ss += '9';
//cout << ss << endl;
int res = calculate(ss);
return make_pair(res,ss);
}
void dfs(int idx, vector<char>& res) {
// 如果已经到9了则判断当前res是否==110如果等于则记录该res并返回,否则直接返回
if (idx == 8) {
int sum = cal2(res).first;
if (sum == 110) {
legal_operate.push_back(res);
return;
}
else {
return;
}
}
for (auto op : operate) {
// idx==7
res.push_back(op);
dfs(idx + 1, res);
res.pop_back();
}
}
int main()
{
vector<int> num = { 1,2,3,4,5,6,7,8,9 };
vector<char> res;
vector<char> op2= { '*','+','*','-','+','*','-','+' };
vector<char> operator1 = { '+','*','*','-','+','*','*','*' };
//cout << cal2(op2);
dfs(0, res);
//cout << legal_operate.size();
for (auto vec : legal_operate) {
cout << cal2(vec).second<<endl;
for (auto x : vec)
cout << x << ' ';
cout << endl;
}
}