剪格子(第四届蓝桥杯省赛C++A组)

剪格子(dfs)

如图剪开,得到两个部分,每个部分的数字和都是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

在这里插入图片描述

思路

我们分析这个图哈,无论怎么切我们所求的那一部分格子是一定可以从地图的第一个点 向上 下 左 右 四个方向走 能够覆盖到的 以图中为例子 先向下再向右走
就切成了图中的样子

我们枚举所有的切法,找出符合题意的最小路径即可,这里图的数据范围很小,我们用dfs来遍历图即可,我们用 x y记录点的位置 step记录步数(也就是切割的格子数目)sum记录切割格子数字和

废话不多说 上代码

#include<iostream>
using namespace std;
const int N=12;
int map[N][N];
int book[N][N];
int n,m;
int INF=1e8;
int cont;
int dx[4]={0,-1,0,1},dy[4]={-1,0,1,0};
int ans=INF;
void dfs(int x,int y,int step,int sum)
{
    if(cont==2*sum)
    {
        if(step<ans)ans=step;
    }
    for(int i=0;i<4;i++)
    {
        int xx=x+dx[i];
        int yy=y+dy[i];
        if(xx<0||xx>=n||yy<0||yy>=m)continue;
        if(book[xx][yy]==1)continue;
        book[xx][yy]=1;
        sum+=map[xx][yy];
        step++;
        dfs(xx,yy,step,sum);
        book[xx][yy]=0;
        step--;
        sum-=map[xx][yy];
    }
}
int main()
{
    cin>>m>>n;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin>>map[i][j];
            cont+=map[i][j];
        }
    }
    book[0][0]=1;
    dfs(0,0,1,map[0][0]);
    if(ans==INF)cout<<0;
    else cout<<ans;
}
发布了10 篇原创文章 · 获赞 0 · 访问量 189

猜你喜欢

转载自blog.csdn.net/weixin_44460602/article/details/104494609