问题描述 
如下图所示,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 


样例输入2 
4  3 
1  1  1  1 
1  30  80  2 
1  1  1  100 
样例输出2 
10 

 

#include<stdio.h>
#include<string.h>
#include<algorithm>
int n,m,a[12][12],b[12][12],su;
int so[4][2]={1,0,-1,0,0,1,0,-1};  //搜索方向
using namespace std;
int dfs(int x,int y,int sum)
{
    int x1,y1,i,ans=0;
    if(sum==su)    //满足要求,搜索结束,此次搜索有效
        return 1;
    for(i=0;i<4;i++)  //四个方向
    {
        x1=x+so[i][0];  // x1,y1为按方向移动后的坐标
        y1=y+so[i][1];
        if(x1<n && x1>=0 && y1<m && y1>=0)  //判断是否出界
        {
            if(b[x1][y1]==0 && a[x1][y1]+sum<=su)  //判断是否已搜索过&&本次搜索是否可执行
            {
                b[x1][y1]=1;      //标记,代表已搜索该点
                ans=dfs(x1,y1,a[x1][y1]+sum);    //ans代表下一个搜索点到此点的步数
                if(ans)          //如果ans不为零说明后续可走,为0则说明此步不可用,取消标记
                    return ans+1;     
                b[x1][y1]=0;
            }
        }
    }
    return 0;
}
int main()
{
        int i,j,sum=0;
        scanf("%d%d",&m,&n);
        memset(b,0,sizeof(b));
        for(i=0;i<n;i++)
            for(j=0;j<m;j++)
            {
                scanf("%d",&a[i][j]);
                sum+=a[i][j];
            }
        if(sum%2==1)
            printf("0\n");
        else
        {
            su=sum/2;
            b[0][0]=1;
            printf("%d\n",dfs(0,0,a[0][0]));
        }
        return 0;
}

 

posted on 2017-03-09 20:56  benTuTuT  阅读(223)  评论(0编辑  收藏  举报