问题描述
如下图所示,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。
输出格式
输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。
样例输入1
3 3
10 1 52
20 30 1
1 2 3
样例输出1
3
样例输入2
4 3
1 1 1 1
1 30 80 2
1 1 1 100
样例输出2
10
分析:
经典的深搜题,对地图的四个方向进行深搜,通过vis数组标志进行回溯,深搜的时候注意越界问题。根据题目要求输出最小格子数。似乎没什么好说的。下面贴代码
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <cstdio>
using namespace std;
int M,N,Map[10][10],AVE,vis[10][10], Min,Empty;
void dfs( int x , int y , int sum , int Count )
{
if ( sum == AVE )
{
Min = min(Min,Count);
Empty = false;
return;
}
sum += Map[y][x];
Count++;
vis[y][x] = true;
//右
if ( x<M-1 && !vis[y][x+1] )
dfs(x+1,y,sum,Count);
//左
if ( x>0 && !vis[y][x-1])
dfs(x-1,y,sum,Count);
//上
if ( y>0 && !vis[y-1][x] )
dfs(x,y-1,sum,Count);
//下
if ( y<N-1 && !vis[y+1][x] )
dfs(x,y+1,sum,Count);
vis[y][x] = false;
}
int main ()
{
int i , j , k , Count;
scanf ("%d%d",&M,&N);
for ( Count = i = 0 ; i < N ; i++)
{
for ( j = 0 ; j < M ; j++)
{
scanf ("%d",&Map[i][j]);
Count += Map[i][j];
}
}
AVE = Count / 2;
/*
//查看数值是否正确录入
cout<<AVE<<endl;
for ( i = 0 ; i < N ; i++)
{
for ( j = 0 ; j < M ; j++)
{
printf ("%d ",Map[i][j]);
}
cout<<endl;
}
*/
//对一些参数进行初始化操作
memset(vis,0,sizeof(vis));
Min = 65535;
Empty = true;
dfs(0,0,0,0);
if (!Empty)
cout<<Min;
else
cout<<0;
return 0;
}