题目描述
如图 11 所示,3×3 的格子中填写了一些整数。
我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是 6060。
本题的要求就是请你编程判定:对给定的 m\times nm×n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 00。
输入格式
程序先读入两个整数 mm,nn 用空格分割 (m,n<10)(m,n<10) 表示表格的宽度和高度。
接下来是 nn 行,每行 mm 个正整数,用空格分开。每个整数不大于 1000010000。
输出格式
程序输出:在所有解中,包含左上角的分割区可能包含的最小的格子数目。
输入输出样例
输入
3 3
10 1 52
20 30 1
1 2 3
输出
3
输入
4 3
1 1 1 1
1 30 80 2
1 1 1 100
输出
10
说明/提示
第二个用例中:
时限 5 秒, 64M。蓝桥杯 2013 年第四届省赛
思路:利用搜索遍历每一种解决方案,把每种解决方案中格子的个数记录下来,然后输出最少格子数
#include<iostream>
using namespace std;
int g[11][11];
int vis[11][11];
int n, m, num[10010], sum, s, k;
int xx[] = { 1,0,-1,0 };
int yy[] = { 0,1,0,-1 };
void dfs(int x, int y)
{
if (s == sum / 2)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (vis[i][j] == 1) num[k]++;
}
}
k++;
return;
}
for (int i = 0; i < 4; i++)
{
int dx = x + xx[i];
int dy = y + yy[i];
if (dx>=1 && dx<=n && dy>=1 && dy<=m && vis[dx][dy]==0 )
{
vis[dx][dy] = 1;
s += g[dx][dy];
dfs(dx, dy);
s -= g[dx][dy]; //回溯
vis[dx][dy] = 0;
}
}
}
int main()
{
cin >> m >> n;
int i, j;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
cin >> g[i][j];
sum += g[i][j];
}
}
vis[1][1] = 1;
s += g[1][1];
dfs(1, 1);
int minn = num[0];
for (i = 0; i < k; i++)
{
minn = min(minn, num[i]);
}
cout << minn << endl;
return 0;
}
这串代码在洛谷中只能跑过3个测试案例,暂时还没有找到更好的解决方法,呜呜~~