[Blue Bridge Cup] Exam Training 2013 C++A Group Question 9 Cut the grid

Cut lattice 

We cut along the red line in the picture, and got two parts, the sum of the numbers in each part is 60.

The requirement of this question is to ask you to program to determine whether the integer in the given mxn grid can be divided into two parts, so that the sum of the numbers in these two areas is equal.
If there are multiple solutions, please output the minimum number of grids contained in the area containing the top-left grid.   
If it cannot be divided, 0 is output

Program input and output format requirements: the
program first reads two integers mn, separated by spaces (m,n<10) to
indicate the width and height of the table.
Next are n rows, each with m positive integers, separated by spaces. Each integer is not greater than 10000. The
output of the program: In all the solutions, the smallest number of grids that may be contained in the partition area at the upper left corner is included.

For example:
user input:
3 3
10 1 52
20 30 1
1 2 3

The program output:
3

Another example:
user input:
4 3
1 1 1 1
1 30 80 2
1 1 1 100

The program output:
10

 

Problem analysis:

Recursion + backtracking + pruning

Idea: To perform a deep search on the grid, recursion is used, then the change state is the coordinate of each time, and the sum of the records, count is used to record the number of steps taken; the exit is when the total value of the grid exceeds all the sums It can be returned directly when half of the time, and when the whole is equal to half of the sum, you need to compare whether the number of steps that reached half this time is the smallest compared with the previous step; the recursive call of the same state is that each step has four For the four directions, the grids in the four directions are called recursively, and the judgment conditions also need to be paid attention to.

It should be noted that in general, for the traversal of a picture, considering that the original path cannot be repeated (when the traversal cannot be repeated), it is necessary to apply for another space to record whether the address has been visited, that is, the vis array is reopened, and the vis array is not visited. The ones that have been visited are 0, and the ones that have been visited are 1.

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

int m, n;
int g[10][10];
int vis[10][10];	//记录走过的状态 
int total;
int res = 1000;
int count;

void f(int i, int j, int sum, int count){	//变化状态 ->参数 
	//边界,出口条件,当sum和大于总的一半时可以返回 
	if(sum > total / 2){
		return ;
	} 
	if(sum == total / 2){	//当sum 等于总的一半时,可以剪了,那么把这里 
		res = min(res, count);
		return; 
	}
	
	vis[i][j] = 1; //该格子被访问过了 
	
	//下一步的四个分支
	if(i+1 <= n-1 && vis[i+1][j] == 0){		//保证下一步的格子没有走过	
		f(i+1, j, sum+g[i][j], count+1);
	}
	if(i-1 >= 0 && vis[i-1][j] == 0){
		f(i-1, j, sum+g[i][j], count+1);
	}
	if(j+1 <= m-1 && vis[i][j+1] == 0){
		f(i, j+1, sum+g[i][j], count+1);
	}
	if(j-1 >= 0 && vis[i][j-1] == 0){
		f(i, j-1, sum+g[i][j], count+1);
	}
	
	vis[i][j] = 0; 
} 

int main(int argc, char** argv) {
	cin >> m >> n;	
	
	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			cin >> g[i][j];
			total += g[i][j];
		}
	} 
	
	f(0, 0, 0, 0);
	
	if(res != 1000){
		cout << res;
	}else{
		cout << "0";
	}
	
	return 0;
}

 

Guess you like

Origin blog.csdn.net/weixin_44566432/article/details/115178585