zoukankan      html  css  js  c++  java
  • 求n*m网格内矩形的数目

    问题描述:

      求一个n*m的网格内存在的矩形数目

         例如:

      1*1           有 1 个矩形:1个1*1的矩形

      2*2          有 9 个矩形 :4个1*1的矩形,4个1*2的矩形,1个2*2的矩形

      3*3      有多少个矩形??

      

      。

      。  

    思路一:  总数=a1个1*1的矩形+a2个1*2的矩形+....+b1个2*1的矩形+b2个2*2的矩形+...+x个n*m的矩形;

      根据统计发现规律如下,n*m网格的矩形,包括

        1*1的矩形  n*m个  

        1*2的矩形  n*(m-1)个

        1*3的矩形  n*(m-2)个

        .....

        2*1的矩形  (n-1)*m 个

        2*2的矩形  (n-1)*(m-1)个

        ....

    算法一:

        总数合计=n*m + n*(m-1) + n*(m-2)+....+(n-1)*m + (n-2)*(m-1)+...+)1

            =n*(n+1)/2*(m*(m+1)/2)

            =n*(n+1)*m*(m+1)/4

        

         public int Compute1(int n, int m)
            {
                return n * (n + 1) * m * (m + 1) / 4;
            }

    算法二:

        按照统计逻辑思路进行编写代码

          public int Compute2(int _Width, int _Height)
            {
                Dictionary<string, int> dic = new Dictionary<string, int>();
    
                for (var i = 1; i <= _Width; i++)
                {
                    for (var j = 1; j <= _Height; j++)
                    {
                        var sum = GetCount(i, j);
                        dic.Add(i.ToString() + "," + j.ToString(), sum);
                        _TotalCount = _TotalCount + sum;
                    }
                }
    
                return _TotalCount;
            }
    
            public int GetCount(int x, int y)
            {
                if (x == 1 && y == 1)
                {
                    return _Width * _Height;
                }
                else
                {
                    return (_Width - x + 1) * (_Height - y + 1);
                }
            }
    

     

    思路二:

      动态规划,假设dp[i][j]表示以第 i 行第 j 列的格子为右下角顶点的矩形数目,那么dp[i][j] = 1 + dp[i-1][j] + dp[i][j-1] – dp[i-1][j-1] , 这里的1表示i ,j 位置的格子自身构成1*1的矩形,之所以减去dp[i-1][j-1], 因为dp[i-1][j] 和 dp[i][j-1] 都包含了dp[i-1][j-1]。计算时注意i = 1 和 j = 1的边界条件。最后把所有dp[i][j]加起来就是我们所求的答案。以3*3网格举例,为了计算方便,红色为设置的边界值,黑色的才是最后需要加起来的值(结果为36)

    image

    int rectNum(int row, int column)
    {
        vector<vector<int> >dp(row+1, vector<int>(column+1, 1));
        int res = 0;
        dp[0][0] = 2;
        for(int i = 1; i <= row; i++)
            for(int j = 1; j <= column; j++)
            {
                dp[i][j] = 1 + dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1];
                res += dp[i][j];
            }
        return res;
    }
    

    思路三:

    我们假设网格是1行m列的,那么总的矩形数目 = m(1*1的矩形) + m-1(1*2的矩形) + m-2(1*3的矩形) +…+1(1*m的矩形) = m*(m+1)/2,同理n行1列总的矩形数目是n*(n+1)/2. 对于n*m的网格,我们可以先确定好选取的行数(即确定矩形的高),公共有n*(n+1)/2种选法,选好以后就可以压缩成1行m列的网格来考虑了,因此总共n*(n+1)/2*m*(m+1)/2个矩形

    int rectNum(int row, int column)
    {
        return row*(row+1)*column*(column+1)/4;
    }
    

      

      

     

  • 相关阅读:
    MySQL的安装问题
    初识二分法
    PK赛 lower_bound( )和upper_bound( )的应用
    记录
    "双指针"去重有序数组
    归并排序(循序渐进中......)
    [2021.4.20打卡]LeetCode781. 森林中的兔子
    杂记...(持续更新)
    [未完待续](c++实现)八数码Ⅱ
    [回忆向]快速排序(降序) 感悟
  • 原文地址:https://www.cnblogs.com/workformylove/p/3745037.html
Copyright © 2011-2022 走看看