二维数组传参和一维差不多,格式为f(b)和void f(b[][N]);
注意,在任何函数中修改b的值,都是修改了实参的值;
类比树的遍历,易知本题需要使用图的DFS搜索;
注意,树的分层结构决定了下一个遍历是必定未访问过的,但图却不同,需要建立一个新的映射数组,判断是否访问过;
注意,为了防止映射数组被修改,必须要在每个函数里新建一个judge数组,用映射数组赋值给judge数组,传参的时候,传judge数组。
题目
我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。
本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0。
代码
#include<iostream>
using namespace std;
const int N = 10;
int lattice = 0;
int m, n, min_ = 100;
int aggregate = 0;
void solution(int a[][N], bool b[][N], int i, int j,
int count, int current);
int main()
{
int a[N][N];
bool b[N][N] = {false};
cin>>m>>n;
for(int i = 0; i <= n-1; ++i)
for(int j = 0; j <= m-1; ++j)
{
cin>>a[i][j];
aggregate += a[i][j];
}
//special status
if(0 != aggregate%2)
{
cout<<0;
return 0;
}
aggregate /= 2;
solution(a, b, 0, 0, 1, a[0][0]);
cout<< (min_==100?0:min_);
return 0;
}
void solution(int a[][N], bool b[][N], int i, int j,
int count, int current)
{
//save the status
bool judge[N][N];
for(int k = 0; k <= n-1; ++k)
for(int l = 0; l <= m-1; ++l)
judge[k][l] = b[k][l];
//traverse the current place
judge[i][j] = true;
//traverse in a DFS way
if(i != 0)
if(!judge[i-1][j] && current+a[i-1][j] <= aggregate)
solution(a, judge, i-1, j, count+1, current+a[i-1][j]);
if(i != n-1)
if(!judge[i+1][j] && current+a[i+1][j] <= aggregate)
solution(a, judge, i+1, j, count+1, current+a[i+1][j]);
if(j != 0)
if(!judge[i][j-1] && current+a[i][j-1] <= aggregate)
solution(a, judge, i, j-1, count+1, current+a[i][j-1]);
if(j != m-1)
if(!judge[i][j+1] && current+a[i][j+1] <= aggregate)
solution(a, judge, i, j+1, count+1, current+a[i][j+1]);
//end condition
if(current == aggregate && count < min_)
{
min_ = count;
}
}