计蒜客 - 组合运算式

时间限制 1000ms 空间限制 65536K

题目描述

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

输入为一行,包含一个整数N3≤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

【思路】

    数据很小,暴力枚举即可,按照字典序从小到大枚举即从前往后按先放空格,再放加号,最后放减号的顺序枚举,递归结束时计算并判断表达式值是否为零,为零做输出即可。就是一定要注意字符串结尾的那个’\0’千万别忘了。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

int n, i, j;
char gap[50];
char cpy[50];

int calc() {
	int len = 0;
	for (int i = 0; i < j; i++) {
		if (' ' != gap[i]) cpy[len++] = gap[i];
	}
	cpy[len] = '\0';//因为这句忘写了,结果错误,检查了好半天,打代码细心还是很重要的

	int ans = 0, tmp = 1, i = 0;
	while (i < len) {
		ans += tmp*atoi(cpy + i);
		while (isdigit(cpy[i])) i++;
		tmp = cpy[i] == '+' ? 1 : -1;
		i++;
	}
	return ans;
}

void solve(int k) {
	if (k == j) {
		if (0 == calc()) printf("%s\n", gap);
		return;
	}
	gap[k] = ' ';
	solve(k + 2);
	gap[k] = '+';
	solve(k + 2);
	gap[k] = '-';
	solve(k + 2);
}

int main() {
	while (scanf("%d", &n) == 1) {
		memset(gap, 0, sizeof(gap));
		memset(cpy, 0, sizeof(cpy));
		for (i = 1, j = 1; i <= n; i++, j += 2) {
			gap[j - 1] = i + 48;
			if (j == 2 * n - 1) break;
		}
		solve(1);
	}
	return 0;
}

posted @ 2017-10-26 00:32  不想吃WA的咸鱼  阅读(225)  评论(0编辑  收藏  举报