蓝桥——剪格子

问题

如下图所示,3  x  3  的格子中填写了一些整数。
+--*--+--+
|10*  1|52|
+--****--+
|20|30*  1|
*******--+
|  1|  2|  3|
+--+--+--+ 
我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。
本题的要求就是请你编程判定:对给定的m  x  n  的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。 
如果无法分割,则输出  0。

例:

输入一个 3 x 3 的数组:

10  1   52

20  30  1

1    2    3

输出:3


题解

1.算法

  1. 从左上角第一个格子开始进行深度优先搜索,从上下左右四个方向去进行递归搜索,可以进行递归的条件是  1)要递归的下一个格子为被设置访问标记  2)在数组内,未出界。
  2. 每走一步,就计算走过的格子的和是多少,再计算没走过的格子的和是多少。如果两个和相等,就代表符合条件,然后我们尝试是否可以更新result(我们需要的答案),如果走过的格子数比result小,就可以更新。
  3. 最后递归完成后将递归过的格子的访问标记清除。

2.代码(C)

#include <stdio.h>
int a[10][10];
int flag[10][10];//标记数组 
int result=10000000;//记录结果 
int m,n;//记录数组大小 
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//用于记录四个方向的x,y变化(上左下右) 

void dfs(int x,int y,int sum)    //x,y记录坐标,sum记录走到这步的和 
{
	int i,j;
    sum=sum+a[x][y];
    flag[x][y]=1;
    //计算另一部分和 
    int sum_other=0; 
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
        {
            if(flag[i][j]==0)    //0代表没有走过的点 
            sum_other=sum_other+a[i][j];
        }
    //判断两部分是否相等 
    if(sum_other==sum)
    {
        int num=0;    //计算被标记的格子数 
        for(i=0;i<n;i++)
            for(j=0;j<m;j++)
                if(flag[i][j]==1)    num++;
        if(num<result)    result=num;
        return;
    }
    //向4个方向递归 
    for(i=0;i<4;i++)
    {
        int tx=x+dir[i][0];
        int ty=y+dir[i][1];
        if(x>=0 && x<n && y>=0 && y<m &&flag[tx][ty]==0)
        {
            dfs(tx,ty,sum);
        }
    }
    flag[x][y]=0;    //四个方向全部遍历完都没有解,那么取消标记 
}
int main()
{
	int i,j;
    scanf("%d %d",&m,&n);
    for(i=0;i<n;i++)    //n行m列 
        for(j=0;j<m;j++)
            scanf("%d",&a[i][j]);
            
    dfs(0,0,0);
    printf("%d",result);
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值