剪格子

来源:互联网 发布:云计算经济效益 编辑:程序博客网 时间:2024/05/16 02:03
标题:剪格子

    如图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


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

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

图片

图片

#include <iostream>#include <queue>using namespace std;int r,c;struct ha{int s[10][10];};typedefstruct ha HX;int _d(int _s[][10]){int t=0;for(int i=0;i<c;i++){for(int q=0;q<r;q++){if(_s[i][q]){t+=1;}}}if(_s[0][0]==1){return t;}return c*r-t;}int _c(int _s[][10]){for(int i=0;i<c;i++){for(int k=0;k<r;k++){if(_s[i][k] == 0){return 0;}}}return 1;}int sum,sum2;int _b(int s[],int _s[][10]){sum=0;sum2=0;for(int i=0;i<c;i++){for(int k=0;k<r;k++){if(_s[i][k]){sum+=s[i*r+k];}else{sum2+=s[i*r+k];}}}if(sum==sum2){return 1;}return 0;}int main(){HX tmp={0};queue<HX> dl;int s[100]={0};cin>>r>>c;for(int g=0;g<r*c;g++){cin>>s[g];}tmp.s[0][0] = 1;dl.push(tmp);while(dl.size()>0){if(_b(s,dl.front().s)){cout<<_d(dl.front().s)<<endl;return 0;}for(int i=0;i<c;i++){for(int k=0;k<r;k++){tmp.s[i][k]=dl.front().s[i][k];}}for(i=0;i<c;i++){for(int k=0;k<r;k++){if(tmp.s[i][k]==1&&!_c(tmp.s)){if(k+1<r&&tmp.s[i][k+1]==0){tmp.s[i][k+1]=1;dl.push(tmp);tmp.s[i][k+1]=0;}if(k-1>=0&&tmp.s[i][k-1]==0){tmp.s[i][k-1]=1;dl.push(tmp);tmp.s[i][k-1]=0;}if(i+1<c&&tmp.s[i+1][k]==0){tmp.s[i+1][k]=1;dl.push(tmp);tmp.s[i+1][k]=0;}if(i-1>=0&&tmp.s[i-1][k]==0){tmp.s[i-1][k]=1;dl.push(tmp);tmp.s[i-1][k]=0;}}}}dl.pop();}cout<<0<<endl;return 0;}