历届试题 剪格子

来源:互联网 发布:工商银行 人工智能 编辑:程序博客网 时间:2024/04/26 21:18
问题描述

如下图所示,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。

输出格式
输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。
样例输入1
3 3
10 1 52
20 30 1
1 2 3
样例输出1
3
样例输入2
4 3
1 1 1 1
1 30 80 2
1 1 1 100
样例输出2

10

不得不说,这道题目又耗费了我整整一天半的时间,当然昨天头疼什么也想不到。在网上看各种别人写的代码,他们全部都是用深度优先搜索去做的,我觉得没有道理啊。

因为不一定所有的格子都是在一个枝丫上的呀。

就好像是一棵从以(0,0)为根节点的树,它的左枝上取一些,右枝上取一些,拼起来才是答案呢。

// jinjintang.cpp : 定义控制台应用程序的入口点。////#include "stdafx.h"#include<iostream>#include<cstdlib>#include<cstring>#include<cmath>#include<queue>#include<algorithm>#include<vector>#include<algorithm>using namespace std;const int maxn=15;int n,m;int a[maxn][maxn];int b[4]={1,-1,0,0};int c[4]={0,0,1,-1};struct node{int x, y;node(int x,int y):x(x),y(y){}};int vis[maxn][maxn]={0};bool can(int x,int y){if(x<0||y<0||x>=n||y>=m||vis[x][y]==1)return false;return true;}int sum=0;int res;int step;int ans=0; int inqu[maxn][maxn]={0};void dfs(int x,int y,queue<node>q){//queue传值是拷贝了一份 不会影响原来的 queue里面装的是下面可能被取到的格子,也就是和现在已经累加的格子相邻的高格子 if(ans>=step)return;//剪枝,如果到目前累计到的格子数比现在的最少格子数还多或者相等,ok 你不用往下搜了! int inqu2[maxn][maxn];//本来想把inqu作为参数传递的,结果想起来数组在函数中传递的是地址,会把这一层的inqu也给改掉 memcpy(inqu2,inqu,sizeof(inqu));//inqu标记有没有进过队列中vis[x][y]=1;//vis数组标记的是这个格子的数有没有被加过sum+=a[x][y];ans++;//没进入一次dfs就先加上它的值,最后再回溯,回溯的两种方法一种是在函数里面进行回溯,一种是在函数外面进行回溯,   if(sum==res){step=ans;}for(int i=0;i<4;i++){int x1=x+b[i];int y1=y+c[i];if(can(x1,y1)&&inqu[x1][y1]==0){node no=node(x1,y1);    inqu[x1][y1]=1;q.push(no);}}while(!q.empty()){//所谓的深度优先和广度优先相结合 就是先用广度优先把兄弟节点全部放到队列里面 然后在用深度优先计算每一个节点子树的合适的值 node no=q.front();q.pop();int x1=no.x;int y1=no.y;dfs(x1,y1,q);}sum-=a[x][y];ans--;vis[x][y]=0; memcpy(inqu,inqu2,sizeof(inqu));}int main(){//freopen("c://jin.txt","r",stdin);cin>>m>>n;step=m*n;int maxm=0;for(int i=0;i<n;i++)for(int j=0;j<m;j++){cin>>a[i][j];if(maxm<a[i][j])maxm=a[i][j];res+=a[i][j];}if(res%2)cout<<0;else{res/=2;if(res<maxm)cout<<0;else{inqu[0][0]=1;queue<node>q;dfs(0,0,q);cout<<step;}}return 0;}




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 龙须树叶子下垂怎么办 文竹的叶子不旺怎么办 问道代金券多了怎么办 洛奇英雄传卡肉怎么办 眼睛被电焊打了怎么办 电弧光打了眼睛怎么办 被电焊光伤了眼怎么办 被弧光闪了眼睛怎么办 乌龟下面壳烂了怎么办 小孩卵圆孔未闭合该怎么办 刚辞职又后悔了怎么办 隼羽头饰卖了怎么办 u盘变成只读了怎么办 小孩被蟑螂咬了怎么办 被蟑螂咬出血了怎么办 多肉植物张长了怎么办 蟹爪莲叶子蔫了怎么办 混沌与秩序2延迟怎么办 混沌与秩序2脸书怎么办 ios炉石传说卡门怎么办 狗狗对主人低吼怎么办 吹雪之松锦徒长怎么办 武装突袭被禁了怎么办 眼球小血管破了怎么办 眼睛白眼球破了怎么办 打拳击手腕伤了怎么办 上眼皮进东西了怎么办 眼睛进了异物怎么办妙招 眼睛毛血管破了怎么办 怪物猎人x钱不够怎么办 小米2开不了机怎么办 3ds更新系统不动怎么办 u盘中病毒了怎么办 aj5白银前面皱了怎么办 狗吃了巧克力该怎么办 孩子零食吃多了怎么办 上学时月经侧漏怎么办 漏电被电的脚肿怎么办 走路有尿溢出来怎么办 篮球气嘴漏气了怎么办 暗线插座盒坏了怎么办