Title Description
Problem description
As shown in the figure below, some integers are filled in the grid of 3x 3.
+–*–+–+
|10* 1|52|
+–**–+
|20|30* 1|
*–+
| 1| 2| 3|
+–+–+–+
We cut along the asterisk line in the figure to get two parts, each of which has a sum of 60 digits.
The requirement of this question is that you program to determine whether integers in a given m x n lattice can be divided into two parts so that the numbers of these two regions are equal.
If there are multiple solutions, output the minimum number of lattices contained in the area containing the upper left corner lattice.
If it cannot be split, output 0.
Input format
The program first reads in two integers m n and divides them into spaces (m, n < 10).
Represents the width and height of the table.
Next is n rows, m positive integers per row, separated by spaces. Each integer is less than 10,000.
Output format
Output an integer representing the smallest number of cells that the partition containing the upper left corner may contain in all solutions.
Sample input 1
3 3
10 1 52
20 30 1
1 2 3
Sample output 1
3
Sample input 2
4 3
1 1 1 1
1 30 80 2
1 1 1 100
Sample output 2
10
Thinking process
When I get this topic, I think of using dfs, starting from the point in the upper left corner, to sum the weights of the traversed points. If it is less than half of the total weights, I will continue traversing, otherwise I will return. Then save the minimum number of traversal points and output it after traversal.
Then the first data passed when it was first written. But the second data is that half of the ten numbers in a circle on the edge of a 4*3 matrix and half of the two in the middle. In this case, I initially set the path down, otherwise the setting of going right would not be satisfied.
I also wondered if it would be better to give priority to breadth. But then suddenly get if is actually the process of setting the trial route, so add two more paths. Generally speaking, the process of judgment is to go down, go right if you can't, go up if you can't, and finally go left if you can't. This allows you to traverse the circumference.
Because there will be a situation where return can not jump out, recursion is very dizzy, so we do not force the end of the recursive value here. Instead, let him jump out recursively. In this way, it would be embarrassing if two conditions were met, so two global variables were set. It saves the minimum number of traversal points so that it can jump out without recursion. Or it can jump out directly by flag flag.
Code representation
/*
0v0 AUTHER: 0_Re5et
*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 99999999
int m, n; // Store Side Length Information
int **p, **visited; // p Storage Weight, Traversal Information of visited Storage Points
int boom=0, haha=0; // boom is the sum of the weights of the points traversed now, and haha is half the sum of the arrays.
int Num=0, NUM=MAX; // Num stores the number of points when the boom and haha are equal, and NUM stores the minimum value of Num.
void dfs(int x, int y)
{
int i, j;
// If the coordinates are beyond the range of the array, return
if(x >= m || y >= n)
{
return;
}
// Add the weight of the traversed point to boom and mark it as set 1
boom = boom + p[x][y];
visited[x][y] = 1;
// Output visited array to view traversal
// printf("now: %d, %d boom: %d\n", x, y, boom);
// for(i=0; i<m; i++)
// {
// for(j=0; j<n; j++)
// {
// printf("%d ", visited[i][j]);
// }
// printf("\n");
// }
// printf("\n");
// system("pause");
// When boom and haha are equal, record Num and update NUM
if(boom == haha)
{
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
{
if(visited[i][j] == 1)
{
Num++;
}
}
}
if(Num < NUM)
{
NUM = Num;
}
}
// Provision of depth traversal path
while(x < m && y < n)
{
// When the array does not exceed the limit and the point has not been accessed and the weight is less than haha, go down first.
if((x+1 < m && y < n) && visited[x+1][y] == 0 && boom < haha)
{
dfs(x+1, y);
}
// Turn right again.
if((x < m && y+1 < n) && visited[x][y+1] == 0 && boom < haha)
{
dfs(x, y+1);
}
// Go up again.
if((x-1 >= 0 && y >= 0) && visited[x-1][y] == 0 && boom < haha)
{
dfs(x-1, y);
}
// Turn left again.
if((x >= 0 && y-1 >= 0) && visited[x][y-1] == 0 && boom < haha)
{
dfs(x, y-1);
}
// After the above path is completed, the mark position of the origin is zero, the weight is subtracted from boom and returned.
visited[x][y] = 0;
boom = boom - p[x][y];
return;
}
}
int main()
{
int i, j;
scanf("%d %d", &n, &m);
// Initialize p array space and assign values
p = (int **)malloc(sizeof(int *) * m);
for(i=0; i<m; i++)
{
p[i] = (int *)malloc(sizeof(int) * n);
}
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
{
scanf("%d", &p[i][j]);
}
}
// Initialize visited array space
visited = (int **)malloc(sizeof(int *) * m);
for(i=0; i<m; i++)
{
visited[i] = (int *)malloc(sizeof(int) * n);
}
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
{
visited[i][j] = 0;
}
}
// Calculate the value of haha
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
{
haha = haha + p[i][j];
}
}
haha = haha/ 2;
dfs(0, 0);
// Minimum quantity of output. If it cannot be split, output 0
if(NUM == MAX)
{
NUM = 0;
}
printf("%d", NUM);
return 0;
}
ps: don't Tucao, I named variables, ha ha ha with big guys.