【洛谷 8601】 [蓝桥杯 2013 省 A] 剪格子

发布时间 2023-10-25 14:33:26作者: #Cookies#

# [蓝桥杯 2013 省 A] 剪格子

## 题目描述

如图 $1$ 所示,$3\times 3$ 的格子中填写了一些整数。

![](https://cdn.luogu.com.cn/upload/image_hosting/hsfjsi38.png)

我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是 $60$。

本题的要求就是请你编程判定:对给定的 $m\times n$ 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。

如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。

如果无法分割,则输出 $0$。

## 输入格式

程序先读入两个整数 $m$,$n$ 用空格分割 $(m,n<10)$
表示表格的宽度和高度。

接下来是 $n$ 行,每行 $m$ 个正整数,用空格分开。每个整数不大于 $10000$。

## 输出格式

程序输出:在所有解中,包含左上角的分割区可能包含的最小的格子数目。

## 样例 #1

### 样例输入 #1

```
3 3
10 1 52
20 30 1
1 2 3
```

### 样例输出 #1

```
3
```

## 样例 #2

### 样例输入 #2

```
4 3
1 1 1 1
1 30 80 2
1 1 1 100
```

### 样例输出 #2

```
10
```

## 提示

第二个用例中:

![](https://cdn.luogu.com.cn/upload/image_hosting/3u5omt41.png)

时限 5 秒, 64M。蓝桥杯 2013 年第四届省赛

 

题解:注意dfs是错解:因为可能

3

1 1 1

8 1 1

1 1 1

就没有办法dfs解决,因为dfs本质上是解决“一笔画问题”,卡错

样例较小时可以解决,较大则不可以

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<bits/stdc++.h>
using namespace std;
int ans=1e9,X,Y,n,m,a[12][12],sum,f[12][12];
//int dx[6]={1,0,0,-1};
//int dy[6]={0,1,-1,0};
int b[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
void dfs(int x,int y,int sm,int now){
    if(sm==sum/2){
        if(now<ans && f[1][1]==1) ans=now;
        return ;
    }
    if(sm>sum/2) return ;
    for(int i=0;i<4;i++){
        //X=x+dx[i]; Y=y+dy[i];
        X=x+b[i][0]; Y=y+b[i][1];
        if(X<1 || X>n || Y<1 || Y>m) continue;
        if(f[X][Y]==1) continue;
        
        f[X][Y]=1; 
        dfs(X,Y,sm+a[X][Y],now+1);
        if(ans) return;
        f[X][Y]=0;
        
    }
    return ;
}

int main(){
    freopen("8601.in","r",stdin);
    freopen("8601.out","w",stdout);
    scanf("%d %d",&m,&n);
    //n为行数(高度),m为列数 
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
            sum+=a[i][j];
        }
    if(sum%2!=0){
        printf("0\n");
        return 0;
    }    
    
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            memset(f,0,sizeof(f));
            f[i][j]=1; 
            dfs(i,j,a[i][j],1);
        }
    printf("%d\n",ans);
    return 0;
}