zoukankan      html  css  js  c++  java
  • 计算几个数相加和为16

    ##

    /************************************************************************/
    /*        功能:计算几个数和是否等于16
    /*        日期:2017年12月
    /*        作者:骆国辉
    /************************************************************************/
    
    #include <stdio.h>
    #include <stack>
    #include <vector>
    #include <time.h>
    
    class SumCombine {
    public:
      SumCombine(int* data, int length, int target_value) : numbers(data), num_length(length), target(target_value) {
        result_num = 0;
      }
    
      enum Result { EQUAL = 0, LARGER = 1, SMALLER = 2, INVALID_INDEX = 3, };
      typedef std::vector<int> VecPath;
      struct FuncState { VecPath path; };
    
      int sum_value(const VecPath& path) {
        int sum = 0;
        for (unsigned int i = 0; i < path.size(); i++) {
          sum += numbers[path[i]];
        }
        return sum;
      }
    
      void print_path(const VecPath& path) {
        for (unsigned int i = 0; i < path.size(); i++) {
          printf("%d ", numbers[path[i]]);
        }
        printf("
    ");
      }
    
      Result check_next(const VecPath& path, int index) {
        if (index >= num_length)
          return INVALID_INDEX;
        int sum = sum_value(path) + numbers[index];
        return sum == target ? EQUAL : (sum > target ? LARGER : SMALLER);
      }
    
      void resolve() {
        int current = 0;
        bool done = false;
    
        std::stack<FuncState> func_stack;
        func_stack.push(FuncState());
        
        do
        {
          /*numbers数组从左到右的顺序依次尝试; a~i表示下标索引 */
          FuncState& fs = func_stack.top();
          Result res = check_next(fs.path, current);
          switch (res) {
          case EQUAL: {
            fs.path.push_back(current);  /*找到一条可用的路径*/
            print_path(fs.path);
            result_num++;
    
            /*如满足的path为 a->e,将path弹出e,并继续检测f节点*/
            fs.path.pop_back();
            current++;
            break;
          }
          case LARGER: {
            current++;  /*过大,尝试下个节点*/
            break;
          }
          case SMALLER: {
            /*过小,添加到path,当前state不变,并压入新state,用于回溯; 但若已经是最后一个节点,不再添加到路径; 
            如当前stack为
            [0] a
            检测到 a->e 之和不足,stack更新为
            [1] a->e
            [0] a 
            并继续处理f节点 */
            if (current != num_length - 1) {  
              FuncState newfs = fs;
              newfs.path.push_back(current);
              func_stack.push(newfs);
            }
            current++;
            break;
          }
          case INVALID_INDEX: {
            /*没有可作为路径第一个节点的节点,相当于1~9都曾经作为路径第一个节点处理过,停止循环*/
            if (fs.path.empty()) {
              done = true;
            }
            else {
              /*当前path不可用,恢复到上个state,并继续往下处理,如当前stack为:
              [2] a->e->f
              [1] a->e
              [0] a
              检测发现 a->e->f-> 不通,恢复为 a->e,并从g开始*/
              current = fs.path.back() + 1;
              func_stack.pop();
            }
            break;
          }
          default: break;
          }
        } while (!done);
      }
    
      int get_result_num() { return result_num; }
    
    private:
      int* numbers;
      int num_length;
      int target;
      int result_num;
    };
    
    void test1() {
      int array[] = {
        2, 3, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
        21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
        38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
        55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70 };
    
      time_t startTime = time(NULL);
      SumCombine sc(array, sizeof(array) / sizeof(int), 20);
      sc.resolve();
      printf("result_num=%d, usetime=%d
    ", sc.get_result_num(), (int)(time(NULL) - startTime));
    }
    
    void test2() {
      int array[] = { 9, 5, 2, 3, 4, 1, 7, 6, 8 };
    
      time_t startTime = time(NULL);
      SumCombine sc(array, sizeof(array) / sizeof(int), 16);
      sc.resolve();
      printf("result_num=%d, usetime=%d
    ", sc.get_result_num(), (int)(time(NULL) - startTime));
    }
    
    int main() {
      test1();
      test2();
      getchar();
      return 0;
    }
  • 相关阅读:
    Do You See Me? Ethical Considerations of the Homeless
    ELDER HOMELESSNESS WHY IS THIS AN ISSUE?
    Endoflife support is lacking for homeless people
    html内联框架
    html字体
    html块 div span
    html列表
    html表格
    SQL Server管理员专用连接的使用   作为一名DBA,经常会处理一些比较棘手的服务无响应问题,鉴于事态的严重性,多数DBA可能直接用“重启”大法,以便尽快的恢复生产环境的正常运转,但是多数情况
    如何配置最大工作线程数 (SQL Server Management Studio)
  • 原文地址:https://www.cnblogs.com/tinaluo/p/8134593.html
Copyright © 2011-2022 走看看