zoukankan      html  css  js  c++  java
  • 寻找表达式(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
    ", 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位。

  • 相关阅读:
    shell getopt getopts获取参数
    apache+svn+ladp认证
    SVN 迁移项目分支
    iptables 优先级
    很实用的一篇HTTP状态码
    套路还在——矩阵计算估值
    CU上看到的一个简单的算法帖子
    linux下服务端实现公网数据转发
    c++接口实现与分离(转载)
    c++继承概念
  • 原文地址:https://www.cnblogs.com/chengxuyuancc/p/3210514.html
Copyright © 2011-2022 走看看