Recursion one: replace multiple loops

递归(英语:Recursion),又译为递回,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。递归一词还较常用于描述以自相似方法
重复事物的过程。例如,当两面镜子相互之间近似平行时,镜中嵌套的图像是以无限递归的形式出现的。也可以理解为自我复制的过程。(以上定义来自维基百科[递归])

When we write programs, recursion is often used to solve the following problems:

1. Replace multiple cycles, especially for different problem scales with different cycles.
2. To solve the problem of recursive definition, the related mathematical expressions are defined recursively. Such as the factorial function, Fibonacci (Fibonacci sequence) sequence, Ackerman (Ackerman) function and so on.
3. The problem can be decomposed into smaller scales for solution, or the solution of the problem is composed of smaller scale solutions.

1. Replace multiple loops:

Queen N question:

Enter an integer n, and require n chess queens to be placed on the n*n chessboard, and cannot attack each other, and output all feasible placement solutions.
The requirements for the position of the queens are: no two queens can be on the same horizontal, vertical or diagonal line. 8 Queens Question-Wikipedia

For this question, if the given number is relatively small, we can naturally think that it may be possible to use the multiple loop method, and each level of loop determines that a position symbol does not match. However, since the number of n is uncertain, and n may be relatively large (for example, n is equal to 4, it is not advisable to use multiple loops), so it is difficult for us to judge how many loops to use.

At this time, using recursion to replace multiple loops is a solution to this problem. The specific approach can be as follows:

1. Put the queen in the first row first, corresponding to n columns . There are n possible results at this time. At this time, the queen in the first line is equivalent to being determined .
2. Then place the queen in the second row. Note that the queen in the second row and the queen in the first row must meet the requirements of the question. Since the first line has been determined, the second line will also be determined.
3. By analogy, when there is no conflict between the kth row and the k-1th row, the recursion continues, otherwise, the recursive traversal should start from the beginning.

The following is the C++ code implementation:

#include <iostream>
#include <cmath>
using namespace std;

int N;		
//用来存放第i行的皇后放在那一列,里面的值表示哪一列,从0开始 
int queenPos[100]; 

//表示第k行之前的皇后已经摆放完成了 
void NQueen(int k);

int main() {
    
    
	cin >> N; 
	NQueen(0);
	return 0;
}

void NQueen(int k) {
    
    	//在k-1行摆放好的情况下摆放第k行 
	if (k == N) {
    
    		//k=N则证明找到一个可能的情况,输出
		for (int i = 0; i < N; i++) {
    
    
			cout << queenPos[i] + 1 << " ";
		}
		cout << endl;
	}
	for (int i = 0; i < N; i++) {
    
    //逐个尝试第K个皇后的位置,这里的i表示的列 
		int j; 
		for (j = 0; j < k; j++) {
    
    //和已经摆好的k个皇后的位置进行比较,看是否冲突,这里只遍历到k -1
		 	if (queenPos[j] == i || 
			 	abs(queenPos[j] - i) == abs(k - j)) {
    
    //行之差和列之差相等为对角线,queenPos[j]-i表示列之差,k-j表示行之差。 
			 		break;
			 } 	
		}
		if (j == k) {
    
    	//遍历过程中没有中途退出时则表明第k行中第i列可行
			queenPos[k] = i;
			NQueen(k + 1);	//可行则递归k+1
		} 
	} 
}

Running results: There are 92 total possible results for the 8 queen problem , and 2 total possible results for the 4 queen problem .

Other content about recursion can be viewed:
Recursion II: Solving the problem of recursion definition
Recursion III: Decomposing the problem into smaller scales

Guess you like

Origin blog.csdn.net/weixin_44184990/article/details/105107049