寻找表达式(dfs)

题目来源:微策略2013年校园招聘笔试题
题目描述:

现在有一个序列123......N,其中N介于3和15之间,要求在序列之间加入+、-或者空格,使得该序列组成的数学表达式的运算结果为0。

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入整数N(3<=N<=15),代表这个序列的长度。

输出:

对应每个测试案例,输出所有使得表达式结果为0的组合,当有多个组合时,按字典序进行排序输出。

样例输入:
3

6
样例输出:
1+2-3

1 2+3-4-5-6
提示:

 1_2+3-4-5-6相当于12+3-4-5-6(‘_’代表空格)

思路:

  对于3<=n<=15,总共有3^n种情况,当n=15时,总共有14348907种情况,所以对于给定的n,我们都可以在1秒内穷举完。对于穷举,当然用dfs是最方便的,我写的代码基本是对所有的情况都遍历一遍,当然如果觉得效率还不行,可以加些适当的减枝。代码如下:

 1 #include <stdio.h>

 2 

 3 int n;

 4 int op[20];

 5 

 6 void print_ans()

 7 {

 8     int i;

 9 

10     for (i = 1; i < n; i ++)

11     {

12         printf("%d", i);

13         if (op[i] == 0)

14             printf(" ");

15         else if (op[i] == 1)

16             printf("+");

17         else

18             printf("-");

19     }

20     printf("%d\n", i);

21 }

22 int is_ok()

23 {

24     int i, ans, temp;

25 

26     if (op[1] == 0)

27         ans = 0;

28     else

29         ans = 1;

30     i = 1;

31     while (i < n)

32     {

33         if (op[i] == 0)

34         {

35             temp = i;

36             while (i < n && op[i] == 0)

37             {

38                 i ++;

39                 if (i >= 10)

40                     temp *= 10;

41                 temp = temp * 10 + i;

42             }

43             ans += temp;

44         }

45         else if  (op[i] == 1)

46         {

47             temp = ++i;

48             while (i < n && op[i] == 0)

49             {

50                 i ++;

51                 if (i >= 10)

52                     temp *= 10;

53                 temp = temp * 10 + i;

54             }

55             ans += temp;

56         }

57         else

58         {

59             temp = ++i;

60             while (i < n && op[i] == 0)

61             {

62                 i ++;

63                 if (i >= 10)

64                     temp *= 10;

65                 temp = temp * 10 + i;

66             }

67             ans -= temp;

68         }

69     }

70     return ans;

71 }

72 void dfs(int index)

73 {

74     if (index == n)

75     {

76         if (!is_ok())

77             print_ans();

78         return;

79     }

80     //空格

81     op[index] = 0;

82     dfs(index + 1);

83     //

84     op[index] = 1;

85     dfs(index + 1);

86     //

87     op[index] = 2;

88     dfs(index + 1);

89 }

90 int main(void)

91 {

92     while (scanf("%d", &n) != EOF)

93         dfs(1);

94     return 0;

95 }
View Code

  关键的代码是dfs函数,分别对空格,加,减进行穷举,op[index]存放了第index位置存放的是哪种情况(0表示空格,1表示加,2表示减),如果index为n,则说明得到了一种可能,函数is_ok就是用于判断当前的情况是否能使得表达式最终的结果为0,如果为0,则输出并返回,否则直接返回。

  is_ok函数是用于判断放在op数组中的表达式是否满足条件,计算表达式比较麻烦的是为空格的情况,由于空格可以首先出现,在“+”后面出现,在“-”后面出现,is_ok中的代码则依次处理这三种情况。还有就是如果空格后面是个2位数,空格前面组成的数要向左移动两位,如果是1位数,只用移动1位。

 

你可能感兴趣的:(表达式)