CSP-homework Week3 ProblemA DFS two questions - selected number of issues and explain the eight queens problem (C ++)

Overview

This road is mainly related to the subject of DFS thought, and gives the solution process will also be another classic track DFS + ------- pruning problem given eight queens problem solving process.

Topic one: the number of election issues

Original title description

Given n positive numbers, ZJM can select exactly K of them that sums to S. Now ZJM wonders how many ways to get it!

INPUT

The first line, an integer T<=100, indicates the number of test cases. For each case, there are two lines. The first line, three integers indicate n, K and S. The second line, n integers indicate the positive numbers.

OUTPUT

For each case, an integer indicate the answer in a independent line.

SAMPLE INPUT

1
10 3 10
1 2 3 4 5 6 7 8 9 10

Sample Output

4

Title repeat

Relatively simple question is intended, each time n digital input, this input digital sample T inside, selects K number (each digit can only be selected once), and so that their sum is equal to a value S, a total of Solving there are many kinds of such combinations.
T entire solution process were performed twice, i.e., executing T solving the above-described process.

Problem-solving ideas

Overview ideas

Board questions DFS ideas, use an array to store each point whether or not been visited, as do some processing in the DFS process :( Note: The selected number of chosen_num, the sum chosen_value selected value, limit the number of K an object value S)

Happening Action taken
chosen_num==K && chosen_value==S The number of combinations of +1
chosen_num<K && chosen_value>=S Pruning discarded
chosen_num<K&& chosen_value<S DFS were down

This strategy can be adopted in all cases enumerated

data storage

use

int store[20];

Storing each access point, the initialization of all the points is set to 0, the process DFS accessed if it is set to 1
To be careful of: DFS continue down portion, if a number is added to the selection numbers, Store [a] is set to 1, after the completion of the downward recursive DFS, the Store [a] is reset to 0, it can guarantee when the same layer selected values available in store array is identical.
code show as below:

for(int i=begin;i<positive_number;i++)
           {
           	if(store[i]==0)
			{
           	   store[i]=1;
               dfs(number+1,addtion+store_number[i],i+1);
           	}
           	store[i]=0;//保证同层选择新数时,访问数组store[]情况完全一致
           }

A topic summary

A relatively simple problem Dfs board, but be aware that if you do not add access to an array reset operation after a dfs down, it will lead to larger problems dfs process occurs when an error has occurred here in handwriting, debugging leads several times before successfully accept.

Improved point a topic

No

A source title

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int store_number[20];
int store[20];//存放每个点是否被访问过
int positive_number=0;//可供选择的数字个数
int add_number=0;//累计的数字个数
int num_addition=0;//累计的数字和
int sum_kind=0;//组合种类的个数
void dfs(int number,int addtion,int begin)
{
    if(number==add_number && addtion==num_addition)
    {
        sum_kind++;
    }
    else if(number<add_number)
    {
       if(addtion>=num_addition)
       return;
       else
       {
           for(int i=begin;i<positive_number;i++)
           {
           	if(store[i]==0)
			{
           	   store[i]=1;
               dfs(number+1,addtion+store_number[i],i+1);
           	}
           	store[i]=0;
           }
       }
    }
    
}
int main()
{
    int bfs_times=0;
    cin>>bfs_times;
    for(int i=0;i<bfs_times;i++)
    {
    	for(int k=0;k<20;k++)
    	{
    		store[k]=0;
		}
        cin>>positive_number>>add_number>>num_addition;
        for(int j=0;j<positive_number;j++)
            cin>>store_number[j];
        dfs(0,0,0); 
        cout<<sum_kind<<endl;
        sum_kind=0;
    }
}

Topic two: eight queens problem

Original title description

Eight queens problem is a DFS Classic title, the title probably is described as follows:
In chess, the queen of the attack and the scope of the Bank in this column to change the center point of the diagonal. Existing chess board a 8 × 8, and try to put on this board open 8 queens so that they do not attack each other, if there are multiple solutions, output try all solutions.

OUTPUT

Output of all possible results.

Sample Output

One possible result of sample output:

1 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0

Title repeat

Eight queens problem is a search problem on a map, find each case, to meet the eight Queens are placed on the board, and each row and diagonal Queens where no other queen, the output of all cases.

Problem-solving ideas

Overview ideas

From line 0 to start placing Queens, each placed in a new location, to test its placement on this, see the position of the Bank in this column and diagonal whether the Queen has been placed, if there is no legitimate explanation, for the DFS down, the sub-law point reset and try the next point of the Bank until filled with 8 rows, the output of the display program.
For check function, the use of large, encapsulates it, the code below:

bool check_right(int x, int y, int map[8][8])
{
	int left_x, left_y, right_x, right_y = 0;
	if (x == 0)
	{
		return true;
	}
	for (int i = 0; i < x; i++)
	{
		if (map[i][y] == 1)
		{
			return false;
		}
	}
	left_x = x-1; left_y = y-1;
	right_x = x-1; right_y = y+1;
	while (left_x >= 0 && left_y >= 0)
	{
		if (map[left_x][left_y] == 1)
		{
			return false;
		}
		left_x = left_x - 1;
		left_y = left_y - 1;
	}
	while (right_x >= 0 && right_y < 8)
	{
		if (map[right_x][right_y] == 1)
		{
			return false;
		}
		right_x = right_x - 1;
		right_y = right_y + 1;
	}
	return true;
}

data storage

Use two-dimensional array map [] [] to hold every position across the board whether to put the queen. Initialization is set to 0, if the queen placed in this position is legitimate, it is set to 1. The
above subject is noted that a similar point, map the array is set to 1 and the pilot legality verification operation is completed, to the point reset, to ensure that when the same layer as DFS, where the board is completely consistent. Reset section key code as follows:

for (int the_col = 0; the_col < 8; the_col++)
	{
		map[row][the_col] = 1;
		if (check_right(row, the_col, map))
		{
			if (row == 7)
				print(map);
			else
				dfs(row + 1, map);
		}
		map[row][the_col] = 0;
	}

Topic two summary

After two questions were handwritten and analyzes its characteristics, general characteristics can be concluded that the DFS class questions:
1, maintains a record is accessed the data structure that point, one-dimensional array may be an array or high, the specific forms meaning of the questions related.
2, in the process of downward DFS, each find a new point, you want to judge the legitimacy of the legal and then continue down marking at the array of records accessed, sub-rule to skip the point were at a point.
3, when the access points in the same layer, select, if a legitimate point to find the next DFS, in which a layer selected before the new point, you want to modify this array of access to records to make do reset to ensure the same point when selecting a new layer, record access the array values are exactly the same.

Topic two points of improvement

For the eight queens problem of optimization is a long-term problem in question, which is more common when there are other lines except the first line put a new piece, the existing situation to see, you do not need to try those in this column or have the Queen on this point diagonal, namely the feasibility of pruning to maximize reduce the number of enumeration, will follow the corresponding source code optimization and optimization of real-time location updates. If Takami, please advise generous.

Title two Source

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;
int number = 0;
bool check_right(int x, int y, int map[8][8])
{
	int left_x, left_y, right_x, right_y = 0;
	if (x == 0)
	{
		return true;
	}
	for (int i = 0; i < x; i++)
	{
		if (map[i][y] == 1)
		{
			return false;
		}
	}
	left_x = x-1; left_y = y-1;
	right_x = x-1; right_y = y+1;
	while (left_x >= 0 && left_y >= 0)
	{
		if (map[left_x][left_y] == 1)
		{
			return false;
		}
		left_x = left_x - 1;
		left_y = left_y - 1;
	}
	while (right_x >= 0 && right_y < 8)
	{
		if (map[right_x][right_y] == 1)
		{
			return false;
		}
		right_x = right_x - 1;
		right_y = right_y + 1;
	}
	return true;
}
void print(int map[8][8])
{
	number++;
	cout<<number<<":" <<endl;
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			if(map[i][j]==0)
			cout<<"0"<<" ";
			else
			cout<<"1"<<" "; 
		}
		cout << endl;
	}
}
void dfs(int row, int map[8][8])
{
	for (int the_col = 0; the_col < 8; the_col++)
	{
		map[row][the_col] = 1;
		if (check_right(row, the_col, map))
		{
			if (row == 7)
				print(map);
			else
				dfs(row + 1, map);
		}
		map[row][the_col] = 0;
	}
}
int main()
{
	int map[8][8];
	memset(map, 0, sizeof(map));
	dfs(0, map);
	cout <<"八皇后问题的解决方案数量有:"<< number<<"个";
	return 0;
} 
Published 17 original articles · won praise 2 · Views 1663

Guess you like

Origin blog.csdn.net/qq_43942251/article/details/104757882