剪格子(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;
}