问题描述
如下图所示,3 x 3 的格子中填写了一些整数。
±-–±-+
|10 1|52|
±-***–+
|20|30 1|
*******–+
| 1| 2| 3|
±-±-±-+
我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。
本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0。
输入
程序先读入两个整数 m n 用空格分割 (m,n< 10)。
表示表格的宽度和高度。
接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000。
输出
输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。
样例输入
3 3
10 1 52
20 30 1
1 2 3
样例输出
3
c语言代码
#include <stdio.h>
int n,m,a[101][101],b[101][101],s,cou=1000;
int dx[4]={0,1,0,-1}; //左下上右四个方向
int dy[4]={1,0,-1,0};
void dfs(int sum,int i,int j,int bs)
{ int k;
if(s==sum*2&&cou>bs) //当sum为s 的一半,记录下块数
{
cou=bs;
return ;
}
else {
for(k=0;k<4;k++) //每个有四个方向可走
{
int x=i+dx[k];
int y=j+dy[k];
if(b[x][y]==0&&x>=0&&y>=0&&x<n&&y<m&&(sum+a[x][y])<=s/2) //在n*M数组内并且未被走过,加和小于s的一半
{
b[x][y]=1; //标记
dfs(sum+a[x][y],x,y,bs+1);//回溯,清除标记
b[x][y]=0;
}
}
}
}
int main()
{ int i,j;
scanf("%d%d",&m,&n);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
scanf("%d",&a[i][j]); //录入
s+=a[i][j]; //求和
b[i][j]=0; //标记为0
}
if(s%2!=0) //为奇数时肯定不能被分为两半
printf("0");
else {
dfs(a[0][0],0,0,1);
if(cou==1000) //无解
printf("0");
else printf("%d",cou);
}
return 0;
}