[] Data structure and algorithm study notes - "algorithm notes" -10 [recursive]

There are two important concepts Recursion: recursive and boundaries (call) recursive
Example 1: using the recursive solution of n factorial

#include <cstdio>

using namespace std;

int F(int n) {
	if (n == 0) return 1;				//递归边界为0
	else return F(n - 1)*n;				//没有达到递归边界时,使用递归式递归调用下去
}

int main()
{
	int n;
	scanf("%d", &n);
	printf("%d\n", F(n));
	return 0;
}

Example 2: find the n-th term of the Fibonacci sequence

#include "stdafx.h"
#include <cstdio>
using namespace std;

int F(int n) {
	if (n == 1 || n == 2) return 1;			
	else return F(n - 1) + F(n - 2);			
}

int main()
{
	int n;
	scanf("%d", &n);
	printf("%d\n", F(n));
	return 0;
}

Here Insert Picture Description
The above code, in fact, is divide and conquer a reflection of ideological problems F (n) is the combined (n-1) and F (n-2) of two sub-questions F.
Example 3: Full alignment problem (Full Permutation)
Here Insert Picture Description
Here Insert Picture Description

#include "stdafx.h"
#include <cstdio>
const int maxn = 11;
int n, P[maxn], hashTable[maxn] = { false };
using namespace std;

void rowF(int index) {
	if (index == n + 1)		//递归边界
	{
		for (int i = 1; i <= n; i++)
		{
			printf("%d", P[i]);	//输出当前自问题的解
		}
		printf("\n");
		return;
	}
	else			//没有达到递归边界时,使用递归式递归调用下去
	{
		for (int i = 1; i <= n; i++)
		{
			if (hashTable[i] == false)
			{
				P[index] = i;
				hashTable[i] = true;
				rowF(index + 1);
				hashTable[i] = false;
			}
		}
	}
}

int main()
{
	n = 3;
	rowF(1);											//从第一行开始		
	return 0;
}

Example. 4: n queens problem
n queens twenty-two not in the same row of the matrix of n * n, same column, the same on a diagonal line, the number of programs seek legal.The book provides a good idea: taking into account the number per row can only place a queen, the Queen of the row n column in order to write, would be arranged in a 1 to n, which fall into a + full array question test whether the problem in the same diagonal.

#include "stdafx.h"
#include <cstdio>
#include<math.h>
const int maxn = 11;
int count = 0;
int n, P[maxn], hashTable[maxn] = { false };
using namespace std;

void rowF(int index) {
	if (index == n + 1)									//递归边界
	{
		//for (int i = 1; i <= n; i++)	printf("%d", P[i]);	//输出当前问题的解
		//printf("\n");
		bool flag = true;						//表示当前排列为一个合法方案
		for (int i = 1; i <= n; i++)				//遍历任意两个皇后
		{
			for (int j = i + 1; j <= n; j++)
			{
				if (abs(i - j) == abs(P[i] - P[j]))	//如果在同一条对角线上
				{
					flag = false;				//不合法
				}
			}
		}
		if (flag)	count++;			//若当前方案合法,令count+1    这里是否要担心把列的组合算进去呢?   不用,不存在列的组合吗?不存在吗  不存在
		return;
	}
	else												//没有达到递归边界时,使用递归式递归调用下去
	{
		for (int i = 1; i <= n; i++)
		{
			if (hashTable[i] == false)
			{
				P[index] = i;
				hashTable[i] = true;
				rowF(index + 1);
				hashTable[i] = false;
			}
		}								//这里的i是一个列的循环,没有返回,到n即停(当然也可以看成为行服务),所以上面的index==n+1更像是为行服务,一行到头,则输出行/做出合法判断
	}									//为什么行能返回列不会返回导致无限循环呢,因为有个	hashTable[i] = false;吗?
}									   //不是,因为对于列而言,其实只有一个for语句,在这个for语句里,进行完就完了
										//但是对于行而言,它是列语句每个for语句里的一个小的递归(递归的集合直到行结束,然后会回到列的for语句中)

int main()
{
	scanf("%d", &n);
	rowF(1);	//从第一行开始		
	printf("%d\n", count);
	return 0;
}

Note that there's a comment period, to help understand, in fact, for the full array of understanding or thorough enough
The code above train of thought ImproveIn front of the train of thought in essence, it is a brute force method
can be found, for some cases, when a part of the queens have been placed (generated part of the array), the rest of the Empress may not be placed, no matter how legitimate, it is not recursive down a direct return to top
Backtracking definition:If a recursive layer before reaching the boundary, since the facts do not need to lead to a sub-problems recursively any, can directly return to the previous
or less is improved code:

#include "stdafx.h"
#include <cstdio>
#include<math.h>
const int maxn = 11;
int count = 0;
int n, P[maxn], hashTable[maxn] = { false };
using namespace std;

void rowF(int index) {
	if (index == n + 1)									//递归边界
	{	
		count++;			//若当前方案合法,令count+1   
		return;
	}
	else				//没有达到递归边界时,使用递归式递归调用下去
	{
		for (int i = 1; i <= n; i++)				//第i行
		{
			if (hashTable[i] == false)		//第i行还没有皇后
			{
				bool flag = true;
				for (int pre = 1; pre < index; pre++)
				//第index列皇后的行号为i,第pre列皇后的行号为P[pre]
				{
					if (abs(index - pre) == abs(i - P[pre]))
					{
						flag = false;				//同一对角线,冲突
						break;
					}
				}
				if (flag)
				{
					P[index] = i;
					hashTable[i] = true;		//第x行被占用
					rowF(index + 1);			//递归处理第index+1行皇后
					hashTable[i] = false;		//递归完毕,换原第x行未占用
				}
				
			}
		}								
	}									
}									  
										

int main()
{
	scanf("%d", &n);
	rowF(1);	//从第一行开始		
	printf("%d\n", count);
	return 0;
}

Exercise

Eating candy

Description Title
mother name from the field name trip back with a box of chocolates delicious fine name name (N total chocolate box, 20> N> 0).
Mom tells name names can eat a piece of chocolate a day or two.
Assume eat chocolate every day name names, name names and asked how many different kinds of eating chocolate program.
For example:
if N = 1, then the name of the name on the first day to eat it, Total 1 embodiment;
if N = 2, the name can be the name of a food on Day 1, Day 2 eat 1, may be first days to eat 2, a total of two kinds of programs;
if N = 3, then the name of the name of the first day to eat one, the remaining two can be the first day to eat two left one, the names were a total of 2 + 1 = 3 kinds of programs;
if N = 4, the name can be the name of a food on day 1, left 3, may take two on day 1, the remaining two, a total of 3 + 2 = 5 kinds of programs.
Now given N, find the program you write the number of programs Cuisines famous chocolate.
Input
Input only one line, i.e., the integer N.
Output
may be multiple sets of test data for each set of data,
the output of only one line, that is, the number of program names Cuisines chocolate.
Sample input
. 1
2
. 4
sample output
. 1
2
. 5

#include <cstdio>
#include<math.h>
int count;

void func(int index)
{
	if (index == 0) return;
	if (index==1)
	{
		count++;
		return;
	}
	if (index == 2)
	{
		count += 2;
	}
	if (index != 0 && index != 1 && index != 2 )
	{
		for (int i = 1; i <= 2; i++)//这里有没有等号?我觉得有:今天吃i块
		{
			func(index-i);
		}
	}
}

int main()
{
	int N;
	while (scanf("%d", &N) != EOF)
	{
		count = 0;
		func(N);
		printf("%d\n", count);
	}
	return 0;
}

Progression

Title Description
write a request Fibonacci number of recursive function, a value for n, the recursive function is used, the output pattern as follows (see examples).
Input
input of the first sample number behavior m, there are m rows each row next integer n, n does not exceed 10.
Output
corresponding to each output sample required pattern (see sample format).

#include <cstdio>
#include<math.h>
int outputraw[30];

int func(int index)
{
	if (index == 1)
	{
		return 0;
	}
	if (index == 2)
	{
		return 1;
	}
	if (index != 2 && index != 1)
	{
		return func(index - 1) + func(index - 2);
	}
}

int main()
{
	int N,M;
	int temp = 1;
	while (scanf("%d", &M) != EOF)
	{
		for (int j = 0; j < M; j++)
		{
			scanf("%d", &N);
			for (int i = 0; i < N; i++)
			{
				for (int j = temp; j <= 2 * i + 1; j++)
				{
					outputraw[j] = func(j);
					temp = j;
				}
				for (int k = 1; k < N - i; k++)
				{
					printf("  ");
				}
				for (int j = 1; j <= 2 * i + 1; j++)
				{
					printf("%d", outputraw[j]);
					if (j != 2 * i + 1)
						printf(" ");
				}
				printf("\n");
			}
		}
	}
	return 0;
}

Magic pocket

This question will not do!

Description Title
has a magical pocket, the total volume was 40, with some variations of this article pockets, the total volume of these items must be 40. John now there are n items to be obtained, the volume of each item respectively a1, a2 ...... an. John may be selected from some of these items, if the total volume of the object 40 is selected, then use the magic pocket, John these items can be obtained. The question now is, John How many different ways of selecting items.
Input
of the first input line is a positive integer n (1 <= n <= 20), indicates the number of different items. The next n lines, each line has a positive integer between 1 and 40, respectively, give values a1, a2 ...... an a.
The output of
the number of different items selected output mode.

Eight Queens

Title Description
play chess people are very clear: the queen can not eat another piece to the number of steps in the horizontal, vertical, diagonal. How eight queens on the chessboard (8 * 8 squares), so that they can not be eaten by anyone! This is the famous eight queens problem.
8. A method for placement of a queen to meet the requirements of the definition of a corresponding sequence a queen, i.e. a = b1b2 ... b8, where bi is the corresponding number of columns in row i Pendulum Queen located. 8 has been known a total of 92 Queens set of solutions (i.e., 92 different strings Queen).
A given number b, b of the required output strings. String comparison is such that: before Queen Queen disposed string string x y, y if and only if x is smaller than when considered integer.
Input
line 1 is a set of n number of test data, followed by n input lines. Each set of test data representing a line, comprising a positive integer b (1 <= b <= 92)
outputs
the output has n rows, each row corresponding to an input output. The output should be a positive integer, b is the queen of the corresponding string.

#include <string>
#include <iostream>
#include "stdafx.h"
#include<math.h>
#include <cstdio>
int output[100] = { 0 };
int temp[10];
bool hashTable[10] = { false };
int c_count = 1;
int x = 8;

void func_g(int index)
{
	if (index == x+1)
	{
		for (int j = 1; j <= x; j++)
		{
			output[c_count] = output[c_count] * 10 + temp[j];
		}
		c_count++;
		return;
	}
	else
	{
		for (int i = 1; i <= x; i++)
		{
			if (hashTable[i] == false)
			{
				bool flag = true;
				for (int p = 1; p < index; p++)
				{
					if (abs(p - index) == abs(i - temp[p]))
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					temp[index] = i;
					hashTable[i] = true;
					func_g(index + 1);
					hashTable[i] = false;
				}
			}
		}
	}
}

int main()
{
	int n;
	int b[200] = { 0 };

	func_g(1);
	sort(output+1, output + c_count);
	while (scanf("%d", &n) != EOF)
	{
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &b[i]);
			printf("%d\n", output[b[i]]);
		}
	}
}


Published 43 original articles · won praise 4 · Views 1214

Guess you like

Origin blog.csdn.net/weixin_42176221/article/details/101150158