剪格子
Posted 亖嘁
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剪格子相关的知识,希望对你有一定的参考价值。
[蓝桥杯 2013 省 A] 剪格子
题目描述
如图 1 1 1 所示, 3 × 3 3\\times 3 3×3 的格子中填写了一些整数。
我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是 60 60 60。
本题的要求就是请你编程判定:对给定的 m × n m\\times n m×n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0 0 0。
输入格式
程序先读入两个整数
m
m
m,
n
n
n 用空格分割
(
m
,
n
<
10
)
(m,n<10)
(m,n<10)
表示表格的宽度和高度。
接下来是 n n n 行,每行 m m m 个正整数,用空格分开。每个整数不大于 10000 10000 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
提示
第二个用例中:
时限 5 秒, 64M。蓝桥杯 2013 年第四届省赛
#include<bits/stdc++.h>
using namespace std;
int n,m,s,ans,a[11][11],f[4][2]=1,0,-1,0,0,1,0,-1;
bool vis[11][11];
void find(int x,int y,int sum,int nows)
if(nows==s)
ans=sum;
return;
if(nows>s)return;
for(int i=0;i<4;i++)
int xx=x+f[i][0];
int yy=y+f[i][1];
if(xx<1||xx>n||yy<1||yy>m||vis[xx][yy])continue;
vis[xx][yy]=1;
find(xx,yy,sum+1,nows+a[xx][yy]);
if(ans)return;
vis[xx][yy]=0;
int main()
cin>>m>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
s+=a[i][j];
if(s%2)
cout<<0;
return 0;
s/=2;
find(1,1,1,a[1][1]);
cout<<ans;
return 0;
蓝桥杯练习系统历届试题 剪格子 dfs
如下图所示,3 x 3 的格子中填写了一些整数。
|10* 1|52|
+--****--+
|20|30* 1|
*******--+
| 1| 2| 3|
+--+--+--+
我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。
本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0。
程序先读入两个整数 m n 用空格分割 (m,n<10)。
表示表格的宽度和高度。
接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000。
10 1 52
20 30 1
1 2 3
1 1 1 1
1 30 80 2
1 1 1 100
1 /* 2 好像是很直接的dfs+回溯 3 */ 4 5 #include <stdio.h> 6 #include <string.h> 7 #include <iostream> 8 #include <queue> 9 #define inf 100000000 10 using namespace std; 11 12 int mp[20][20]; 13 int ans, sum; 14 int n, m; 15 16 int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}; 17 int vis[20][20]; 18 19 bool check(int a, int b) { 20 if (a >= 0 && a < n && b >= 0 && b < m && !vis[a][b]) { 21 return true; 22 } 23 return false; 24 } 25 26 void dfs(int x, int y, int num, int tsum) { 27 if (tsum == sum/2) { 28 if (ans > num) { 29 ans = num; 30 return; 31 } 32 } 33 34 for (int i=0; i<4; ++i) { 35 int tx = x + dir[i][0]; 36 int ty = y + dir[i][1]; 37 if (check(tx, ty)) { 38 vis[tx][ty] = 1; 39 dfs(tx, ty, num+1, tsum+mp[tx][ty]); 40 vis[tx][ty] = 0; 41 } 42 } 43 } 44 45 int main() { 46 while(cin >> m >> n) { 47 ans = inf; 48 sum = 0; 49 memset(vis, 0, sizeof(vis)); 50 51 for (int i=0; i<n; ++i) { 52 for (int j=0; j<m; ++j) { 53 cin >> mp[i][j]; 54 sum += mp[i][j]; 55 } 56 } 57 58 vis[0][0] = 1; 59 dfs(0, 0, 1, mp[0][0]); 60 cout << ans << endl; 61 } 62 return 0; 63 }
以上是关于剪格子的主要内容,如果未能解决你的问题,请参考以下文章