题目:标题:剪格子
如图p1.jpg所示,3 x 3 的格子中填写了一些整数。
我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是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
再例如:
用户输入:
4 3
1 1 1 1
1 30 80 2
1 1 1 100
则程序输出:
10
(参见p2.jpg)
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 5000ms
思想:数字分组思想,分好了,常规思路
程序实现:
#include<stdio.h>
#include<stdlib.h>
int rowNum;
int colNum;
int **dataValue;
int min = 10000;
int *seedsValue;
void exec_sum()
{
int i;
int sum1 = 0;
int sum0 = 0;
int has1 = 0;
for(i = 0; i < rowNum * colNum; i++){
if(seedsValue[i]){
has1++;
sum1 += dataValue[i /colNum][i % colNum];
}else{
sum0 += dataValue[i /colNum][i % colNum];
}
}
if(sum1 == sum0){
//printf("\n\nthis count%d\n", has1);
/*for(i = 0; i < rowNum * colNum; i++){
if(seedsValue[i]){
printf("%d ", i);
}
}*/
if(has1 < min){
min = has1;
}
}
}
void fun(int count)
{
if(count == rowNum * colNum){
int i ;
exec_sum();
return;
}
seedsValue[count] = 0;
fun(count + 1);
seedsValue[count] = 1;
fun(count + 1);
}
void input_data()
{
scanf("%d %d", &colNum, &rowNum);
int i;
int j;
seedsValue = (int *)malloc(sizeof(int) * rowNum * colNum);
dataValue = (int **)malloc(sizeof(int*) * rowNum);
for(i = 0; i < rowNum; i++){
dataValue[i] = (int *)malloc(sizeof(int) * colNum);
for(j = 0; j < colNum; j++){
scanf("%d", &dataValue[i][j]);
}
}
}
void freeMem()
{
free(seedsValue);
int i;
for(i = 0; i < rowNum; i++){
free(dataValue[i]);
}
free(dataValue);
}
int main(void)
{
input_data();
seedsValue[0] = 1;
fun(1);
if(min == 10000){
min = 0;
}
printf("%d\n", min);
freeMem();
}