如下图所示,3×3 的格子中填写了一些整数。
我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是 60。
本题的要求就是请你编程判定:对给定的 m×n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0。
输入输出格式
输入格式
第一行输入两个整数 m 和 n,表示表格的宽度和高度,每个整数用一个空格隔开。
接下来输入 n 行,每行输入 m 个正整数,每个整数不大于 10000,每个正整数用一个空格隔开。
输出格式
输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。
输入输出样例1
输入
3 3
10 1 52
20 30 1
1 2 3
输出
3
输入输出样例2
输入
2 2
10 15
5 2
输出
0
说明提示
m,n<10
//使用c++深度优先搜索算法解决
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
#define MAX_N 10
vector<vector<int>>grid;
vector<int> temp1;
int res=INT_MAX;
//使用#include<climits>
int ave;
//存储平均值
bool visit[MAX_N][MAX_N];
//记录当前格子又没有被访问
int m,n;
//移动数组
int x[]={-1,1,0,0};
int y[]={0,0,-1,1};
//深度优先搜索解决
void dfs(int index1,int index2,int currsum){
//index1 index2当前到达的位置
//currsum存储范围过的格子数字之和
if(currsum>ave)return;
//剪枝操作
if(currsum==ave){
int temp=temp1.size();
res=min(res,temp);
//记录最小格子数量
return;
}
for(int i=0;i<4;i++){
int a=index1+x[i],b=index2+y[i];
if(!visit[a][b]){
if(a<0||a>=m||b<0||b>=n)continue;
visit[a][b]=true;
temp1.push_back(grid[a][b]);
dfs(a,b,currsum+grid[a][b]);
temp1.pop_back();
//记录格子数量
//回溯,恢复现场
visit[a][b]=false;
}
}
}
int main(){
cin>>m>>n;
int sum=0;
//存储格子
for(int i=0;i<m;i++){
vector<int> temp;
for(int j=0;j<n;j++){
int num;
cin>>num;
sum+=num;
temp.push_back(num);
}
grid.push_back(temp);
}
if(sum%2!=0)
//如果格子是奇数,就一定没有结果
{cout<<0<<endl;
return 0;}
else{
ave=sum/2;
visit[0][0]=true;
//结果要是得到左上角的格子数量,只能从最左上角的位置出发得到搜索
temp1.push_back(grid[0][0]);
dfs(0,0,grid[0][0]);
}
if(res==INT_MAX)//可能没有答案
cout<<0<<endl;
else
cout<<res<<endl;
return 0;
}