• 使用“數制”解組合策略問題


    問題:

    序列123...N,N介于3和9之间,在其中加入+、-或者空格,使其和为0。

    如123456,1-2 3-4 5+6 7,等价于1-23-45+67=0。


    解答:

    網上找來的代碼。

     1 //序列123...N,N介于3和9之间,在其中加入+、-或者空格,使其和为0,
     2 //如123456  1-2 3-4 5+6 7 等价于1-23-45+67=0。请问,如何获得所有组合?使用递归和非递归。
     3 //非递归算法
     4 #include <iostream>
     5 #include <cmath>
     6 using namespace std;
     7 
     8 void func (char* str);
     9 void calc (char* result);
    10 
    11 int main()
    12 {
    13     char str[] = "123456789";
    14     func(str);
    15     return 0;
    16 }
    17 
    18 void func(char* str)
    19 {
    20     //初始化输出数组
    21     int len = strlen(str);
    22     char* result = new char[len*2];
    23     for (int i = 0; i < len; i++)    {
    24         result[i*2] = str[i];
    25     }
    26     result[len*2-1] = '';
    27     
    28     //模拟3进制的运算
    29     char key[3] = {' ', '+', '-'};
    30     int n = pow(3.0, len - 1);
    31     for (int i = 0; i < n; i++)    {
    32         //把i转换成3进制,计算每一位,转换成字符,填入字符串相应位置
    33         int pos = len * 2 - 3; //个位数填入位置
    34         int temp = i, mod;
    35         do {
    36             mod = temp % 3;
    37             temp /= 3;
    38             result[pos] = key[mod];
    39             pos -= 2;
    40         } while (temp > 0);
    41         //高位补0
    42         while (pos > 0)    {
    43             result[pos] = key[0];
    44             pos -= 2;
    45         }
    46         calc(result);  //计算结果并输出
    47     }
    48 
    49     delete[] result;
    50 }
    51 
    52 void calc(char* result)
    53 {
    54     int sum = 0, sign = 1, i = 0;
    55     int temp = 0;
    56     while (result[i] != '')    {
    57         if (result[i] == ' ')    {
    58             temp *= 10;
    59         }
    60         else if(result[i] == '+' || result[i] == '-')    {
    61             sign = (result[i] == '+') ? 1 : -1;
    62             sum += temp;
    63             temp = 0;
    64         }
    65         else {
    66             temp += sign * (result[i] - '0');
    67         }
    68         i++;
    69     }
    70     sum += temp;
    71     if (sum == 0)    {
    72         cout << result << endl;
    73     }
    74 }

    説明:

    序列123...N,在數字之間插入“+”、“-”或“ ”,N 個數字之間有 N-1 個間隔,所以一共有 3^(N-1) 种方法。

    利用“數制”可以輕鬆產生這些組合排列。

    二進制數表示法,就是用01兩個數的組合排列,一個 byte 有 8 個 bits, 就有 2^8 個組合排列數,因此可以表示 [0,255] 這些數。

    十進制數就由十個符號 “0123456789” 組合排列得到。

    現在反向思考,我們需要是所有的組合排列,用一個數字就可以表示一種組合排列。

    所以可以用 [0,3^(N-1)] 這些數表示所有 N 位的三進制數。

    就說這些,我只能說得這麽清楚了。


  • 相关阅读:
    2017D 方格分割
    2017B 等差素数列
    完全平方数
    K-th Number(二分答案+尺取法判断)
    cf634div3
    performSelector: 与 dispatch_time 异同
    UIButton 的属性与方法
    Node.js 学习笔记三
    [2019杭电多校第一场][hdu6578]Blank(dp)
    [2019杭电多校第一场][hdu6582]Path(最短路&&最小割)
  • 原文地址:https://www.cnblogs.com/prajna/p/3346509.html
Copyright © 2020-2023  润新知