历届试题 剪格子

47 篇文章 0 订阅
17 篇文章 0 订阅

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

本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0

p1
p2

程序输入输出格式要求:

程序先读入两个整数 m n 用空格分割 (m,n<10) 表示表格的宽度和高度 接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000 程序输出:在所有解中,包含左上角的分割区可能包含的最小的格子数目。 例如: 用户输入: 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 资源约定: 峰值内存消耗 < 64M CPU消耗 < 5000ms 请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。 所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。 注意: main函数需要返回0 注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。 注意: 所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

//搜索类题目,有可能有没想到的情况;

#include <iostream>
#include <cstdio>
using namespace std;
int a[11][11]={0};
int map[4][2]={{-1,0},{0,1},{1,0},{0,-1}};//4个方向 
int v[11][11]={0};
int sum=0,ss,z=0;
int m,n;
void f()
{
int k=v[0][0];
int i,j;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
if(v[i][j]==k)
z++;
}
int check(int x,int y,int ss)
{
if(x<0||y<0||x>=m||y>=n)
return 1;
if(ss+a[x][y]>sum)
return 1;
if(v[x][y]==1)
return 1;
return 0;
}
void  fun(int x,int y,int ss)
{

if(ss==sum)
{
f();
return ;
}
int i;
for(i=0;i<4;i++)
{
int ix,iy;
ix=x+map[i][0];
iy=y+map[i][1];
if(check(ix,iy,ss)==1)
continue;
v[ix][iy]=1;
fun(ix,iy,ss+a[ix][iy]);
v[ix][iy]=0;

}
}
int main()
{
scanf("%d%d", &n, &m);
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
scanf("%d", &a[i][j]);
sum+=a[i][j];
}
}
if(sum%2==1)
printf("0\n");
else
{
sum/=2;
v[0][0]=1;
fun(0,0,a[0][0]);
printf("%d\n",z);
}
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值