QDUOJ-39 零式求和(深搜)

Problem 39: 零式求和


Time Limit:1 Ms|  Memory Limit:128 MB
Difficulty:3

[Problem]  [Rank]

Description

请考虑一个由1到N(N=3, 4, 5 ... 9)的数字组成的递增数列:1 2 3 ... N。现在请在数列中插入“+”表示加,或者“-”表示减,抑或是“ ”表示空白(例如1-2 3就等于1-23),来将每一对数字组合在一起(请不在第一个数字前插入符号)。计算该表达式的结果并注意你是否得到了和为零。请你写一个程序找出所有产生和为零的长度为N的数列。 

Input

单独的一行表示整数N (3 <= N <= 9)。 

Output

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

Sample Input

7

Sample Output

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

Source

admin


思路:

        因为题目中指出N <9,并且运算符只有三种,所以可以用深搜枚举每一位的运算符,运算符优先级是 “空格>加>减”;

        题目难点在于计算式对空格运算符的处理,即对空格前后数字的合并,此处可以使用普通表达式计算字符串解析的办法进行处理,但考虑到,这儿最多只有9个数,解析还是有点不值当的,所以就想在进行计算之前,先进行合并,方法如下:

比如: 1+2(空格)3(空格)4+5 这种情况,合并后变成 1+234(空格)0(空格)0+5;

具体方法具体方法见下面代码。因为现在只有加减运算不需要考虑优先级,所以在求值时,只需设置一个变量a = num[1], 然后那它不断跟后面的数字进行对应的运算就行了(遇到空格运算不必处理);


代码:

#include <stdio.h>
#define N 15

int n;
char c[N], fh[3] = {' ', '+', '-'};		//运算符可能出现的三种情况

void dfs(int k);
int jisuan();
int qz(int a, int b, char c);

int main()
{
	while(scanf("%d", &n) != EOF){
		dfs(1);
	}

	return 0;
}

void dfs(int k)
{
	if(k == n){
		int ans = jisuan();
		if(ans == 0){
			printf("1");
			for(int i = 2; i <= n; i ++){		//为方便后面的计算,运算符从第二位开始枚举,知道第n位,总共n-1位运算符
				printf("%c%d", c[i], i);
			}
			printf("\n");
		}
		return;
	}
	int t = 0;
	for(int i = 0; i < 3; i ++){
		c[k + 1] = fh[t ++];
		dfs(k + 1);
	}
}

int jisuan()
{
	int i, a;
	int *num = new int[n + 5];
	for(i = 1; i <= n; i ++){				//计算式设置的临时数组,用于合并空格运算符
		num[i] = i;
	}
	for(i = 2; i <= n; i ++){
		if(c[i] == ' ' && num[i - 1] != 0){	//如果当前运算符是空格,并且空格的前一位不是0,那么进行合并
			for(int j = i; j <= n; j ++){
				num[i - 1] = num[i - 1] * 10 + num[j];
				num[j] = 0;		//合并完成后,将空格运算符后面的设置成0
				if(c[j + 1] != ' ')	//如果下一位运算符还是空格,则继续合并
					break;
			}
		}
	}
	a = num[1];
	for(i = 2; i <= n; i ++){
		a = qz(a, num[i], c[i]);			//a保存当前运算的结果,就是那它不断跟后面的数字进行运算
	}

	return a;
}

int qz(int a, int b, char c)
{
	switch(c){
		case ' ':				//合并完成后,计算式遇到空格,只需返回空格前的数字即可
			return a;
		case '+':
			return a + b;
		case '-':
			return a - b;
	}

	return -1;
}


你可能感兴趣的:(深搜)