[ACwing 93] [template] non-recursive combinatorial enumeration - Analog recursion

(Face questions from ACwing)

1 ~ n from the n randomly selected integer number m, the output of all possible options.

Input Format

Two integers  n- , m  , separated by a space on the same line.

Output Format

Outputs of all programs in the order from small to large, one for each row.

First, ASC are arranged in the same row, adjacent two numbers separated by a space.

Secondly, for two different lines, corresponding to the number of subscripts to-one comparison, the smaller lexicographically top surface (e.g., 1357 rows 1368 in the front).

data range

n>0 ,
0mn ,
n+(nm)25

  Positive solution to this problem is to enumerate dfs, it has been mentioned in the previous blog. Considering now the machine to do with analog loop recursive manner.

  The parameters of a function of the current, the position of the recursion level (old top of the stack), and after completion of recursion, a layer of a recursive function should be performed: computerized maintenance system stack implemented recursively, each element of the recording stack three state statements. We simulated stack on top of the stack layer position is obvious, you do not need to record the second argument.

  Recursive process is: Each element of the stack to stack, make sure that it corresponds to the state of execution to which step, this step continues down until you return or face the next recursive call. For example: The following is a function of positive solutions dfs this question, we can put into it, as shown in Listing 3 segments.

  1. void dfs(int x) {  
  2.     //--------#0  
  3.     if (sel.size() > m || sel.size() + n - x + 1 < m)  
  4.         return;  
  5.     if (x == n + 1) {  
  6.         rep(0, m - 1)  
  7.             printf("%d ", sel[i]);  
  8.         puts("");  
  9.         return;  
  10.     }  
  11.     sel.push_back(x);  
  12.   //--------#0
  13.     dfs(x + 1);  
  14.     //--------#1  
  15.     sel.pop_back();  
  16.     //--------#1
  17.     dfs(x + 1);  
  18.     //--------#2  
  19.     return;  
  20. }  

  Based on this body of the function, we use the loop to simulate the process of recursive calls. Defined state state comprises two elements for the current function parameter x, the position of the currently executing function; Note that the status of the stack system and differences. The system records the stack after the function is to return the default position, where performed to demonstrate more directly the current function has been modified. First, the first state {1, 0} stack (call entry corresponding to the main recursive function). Next, enter the loop, we cycle the following statement in the stack is not empty:

  1, the stack, the recording current execution stack location parameters x and cur_addr.

  2, if cur_addr is 0, indicating that the function is executed from the beginning, we have implemented the first stage function 0 body. After machining, let Drawing {x, 1} (paragraph 1 indicates should be performed when the function body to the state passed on the stack), Aberdeen the parameter x + 1 of the next function, performing a function of position in the (0 ) stack. After the cycle continue to the next level;

  3, if cur_addr is 1, a second section which performs the function thereof; stack then we have {x, 2} (paragraph 2 performs the function to return the state thereof), {x + 1, 0} (lower a layer of recursion), the cycle continues.

  4, if cur_addr 2, the current function has finished, do not stack again. Cycle can continue.

Complete the main function of code:

  1. struct State {  
  2.     int x, addr;  
  3.     State(int a, int b):  
  4.         x(a), addr(b) {}  
  5. };  
  6. int main () {  
  7.     cin >> n >> m;   
  8.     stack<State> sta;  
  9.     sta.push(State(1, 0));//dfs(1);  
  10.     while (sta.size()) {  
  11.         int x = sta.top().x, cur_addr = sta.top().addr;   
  12.         sta.pop ();  
  13.         switch (cur_addr) {  
  14.             case 0:  
  15.                 if (sel.size() > m || sel.size() + n - x + 1 < m)  
  16.                     continue;  
  17.                 if (x == n + 1) {  
  18.                     rep(0, m - 1)  
  19.                         printf("%d ", sel[i]);  
  20.                     puts("");  
  21.                     continue;  
  22.                 }  
  23.                 sel.push_back(x);  
  24.                 sta.push(State(x, 1));  
  25.                 sta.push(State(x+1, 0));   
  26.                 continue;  
  27.             case 1:  
  28.                 sel.pop_back();  
  29.                 sta.push(State(x+1, 0));  
  30.         }  
  31.     }   
  32.     return 0;  
  33. }  

  Given the advanced algorithm code system stack the return way more fit, given together here.

  1. #include <iostream>  
  2. #include <cstring>  
  3. #include <cstdio>  
  4. #include <vector>  
  5. using namespace std;  
  6. vector<int> chosen;  
  7. int top, address, sta[100010], n, m;  
  8. inline  void Call ( int X,  int ret_addr) {// stack instruction simulation system call (), the recording parameters for each state and a return statement positions
  9.     int pre = top;  
  10.     sta[++top] = x;  
  11.     sta[++top] = ret_addr;  
  12.     sta [top ++] = on;  
  13. }  
  14. inline  int RET () {// analog command return, and returns de-stacked next statement to be executed
  15.     int ret_addr = sta[top - 1];  
  16.     top = be [top]  
  17.     return ret_addr;  
  18. }  
  19. int main () {  
  20.     cin >> n >> m;  
  21.     call(1, 0);  
  22.     while (top) {  
  23.         you x = sta [top - 2];  
  24.         switch (address) {  
  25.             case 0:  
  26.                 if (chosen.size() > m || chosen.size() + (n - x + 1) < m) {  
  27.                     address = ret();  
  28.                     continue;  
  29.                 }  
  30.                 if (x == n + 1) {  
  31.                     for (int i = 0; i < chosen.size(); ++i)  
  32.                         printf("%d ", chosen[i]);  
  33.                     puts("");  
  34.                     address = ret();  
  35.                     continue;  
  36.                 }  
  37.                 chosen.push_back(x);  
  38.                 call (x + 1, 1); // stack next state
  39.                 address = 0; // next function performed novo
  40.                 continue;  
  41.             case 1:  
  42.                 chosen.pop_back();  
  43.                 call (x + 1, 2); // stack next state
  44.                 address = 0;  
  45.                 continue;  
  46.             case 2:  
  47.                 address = ret (); // current state has been finished, return
  48.         }  
  49.     }  
  50.     return 0;     
  51. }  

 

Guess you like

Origin www.cnblogs.com/TY02/p/11307274.html