• 试题 历届试题 剪格子


    资源限制
    时间限制:1.0s   内存限制:256.0MB
     
    问题描述

    如下图所示,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
     
     
    这题就是简单的深搜. 先求出所有数的总和,判断是否能被2整除,若不能就输出0,能就再深搜判断.
     
    起初我否定了这个想法,因为这样深搜只能找到以(0,0)为端点或者成环的划分区域,但是并不排除有这样的划分区域:(0,0)不在这个区域的端点位置,而是交点位置,例如(0,0)所在行和列同属于一个区域,其他数属于另一个区域,这种划分就搜不出来了. 不过百度了一下发现好多代码也没考虑那么多,交了之后发现原来就3个测试用例,我估计是水过.
     
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <string>
     6 #include <cmath>
     7 #include <algorithm>
     8 #define INF 0x3f3f3f3f
     9 #define zero 1e-7
    10 
    11 using namespace std;
    12 typedef long long ll;
    13 const ll mod=50000;
    14 const ll max_n=2e5+7;
    15 
    16 int mp[10][10];
    17 bool vis[10][10]; //标记是否访问过 
    18 int d[4][2]={{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
    19 int m, n;//n行m列
    20 int ans, res;//所有数字和,最小区域格子数 
    21 
    22 void input() {
    23     ans=0;
    24     for(int i=0; i<n; i++) {
    25         for(int j=0; j<m; j++) {
    26             cin>>mp[i][j];
    27             ans+=mp[i][j];
    28         }
    29     }
    30 }
    31  
    32 void dfs(int x, int y, int sum, int num) {//坐标、区域和、区域格子数 
    33     vis[x][y]=true;
    34     if(sum==ans/2) {
    35         res=min(res, num);
    36         return;
    37     } 
    38     for(int i=0; i<4; i++) {
    39         int dx=x+d[i][0];
    40         int dy=y+d[i][1];
    41         if(dx>=0 && dx<n && dy>=0 && dy<m && !vis[dx][dy] && sum+mp[dx][dy]<=ans/2) {
    42             vis[dx][dy]=true;
    43             dfs(dx, dy, sum+mp[dx][dy], num+1);
    44             vis[dx][dy]=false;//回溯 
    45         }
    46     }
    47 }
    48  
    49 int main() {
    50     cin>>m>>n;
    51     memset(vis, false, sizeof(vis));
    52     res=INF;
    53     input();
    54     if(ans%2==0) dfs(0, 0, mp[0][0], 1);
    55     if(res==INF) res=0;
    56     cout<<res<<endl;
    57     return 0;
    58 } 
  • 相关阅读:
    JAVA基础——异常详解
    Android Studio如何配置adb以及常用命令
    利用Android Studio编写 Android上的c与c++程序
    启动与销毁Activity
    应用资源概览
    Android 开发者文档 -- 应用基础知识
    51单片机最小系统
    同相放大器
    反相放大器
    面向对象开发C++快速入门视频教程 C++基础加实战视频教程
  • 原文地址:https://www.cnblogs.com/wwqzbl/p/13564280.html
Copyright © 2020-2023  润新知