计蒜客——组合运算式

传送门:https://nanti.jisuanke.com/t/59

时间限制:1000ms 内存限制:65536K

请考虑一个被空格分隔的,由1到N的整数组成的递增数列:1 2 3 … N。现在请在数列中插入表示加的“+”,或者表示减“-”,亦或者表示空白的“ ”(例如1-2 3就等于1-23),来将每一对数字组合成一个表达式(第一个数字前无空格)。计算该表达式的结果并判断其值是否为0。请你写一个程序找出所有产生和为零的长度为N的数列。

输入为一行,包含一个整数N(3≤N≤9)。

输出为所有在每对数字间插入“+”, “-”, 或 “ ”后能得到和为零的数列,并按照字典(ASCII码)序排列。

样例输入

7

样例输出

1+2-3+4-5-6+7

1+2-3-4+5+6-7

1-2 3+4+5+6+7

1-2 3-4 5+6 7

1-2+3+4-5+6-7

1-2-3-4-5+6+7

#include <iostream>
#include <set>
#include <cstdio>
#include <sstream>
#include <cctype>
#include <stack>
#include <queue>

using std::string;
std::set<string> fin;
unsigned int n = 0;

bool judge(string expression) {
    int len = expression.length();
    std::stack<int> numbers;
    std::queue<char> ops;
    bool flag = false;

    for (int i = 0; i < len; ++i) {
        if (isdigit(expression[i])) {
            std::stringstream ss;
            ss << expression[i];
            int temp;
            ss >> temp;
            if (flag) {
                temp += numbers.top() * 10;
                numbers.pop();
                numbers.push(temp);
                flag = false;
            }
            else {
                numbers.push(temp);
            }
            ss.clear();
        }
        else if (expression[i] == ' '){
            flag = true;;
        }
        else {
            ops.push(expression[i]);
            flag = false;
        }
    }

    int numbersSize = numbers.size();
    int arr[numbersSize] = {0};
    for (int i = numbersSize; i > 0; --i) {
        arr[i - 1] = numbers.top();
        numbers.pop();
    }
    int expressionEnd = arr[0];
    for (int i = 1; i < numbersSize; ++i) {
        int number = arr[i];
        char op = ops.front();
        ops.pop();
        if (op == '+') {
            expressionEnd += number;
        }
        else if (op == '-') {
            expressionEnd -= number;
        }
    }
    if (expressionEnd == 0) return true;
    else return false;
}


void DFS(int beginNumber, string expression, string op) {
    expression += op;

    std::stringstream ss;
    ss << beginNumber;
    expression += ss.str();
    ss.clear();

    unsigned int nextNumber = beginNumber + 1;
    if (nextNumber > n) {
        if (judge(expression)) fin.insert(expression);
        return;
    }

    // "+"
    DFS(nextNumber, expression, "+");

    // "-"
    DFS(nextNumber, expression, "-");

    // " "
    DFS(nextNumber, expression, " ");

}

int main()
{
    scanf("%d", &n);
    string expression = "\0";
    DFS(1, expression, "\0");

    for (std::set<string>::iterator it = fin.begin(); it != --fin.end(); ++it)
        std::cout << *it << std::endl;
    std::cout << *(--fin.end());

    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值