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;
    }
    

      

      

     

  • 相关阅读:
    257. Binary Tree Paths
    324. Wiggle Sort II
    315. Count of Smaller Numbers After Self
    350. Intersection of Two Arrays II
    295. Find Median from Data Stream
    289. Game of Life
    287. Find the Duplicate Number
    279. Perfect Squares
    384. Shuffle an Array
    E
  • 原文地址:https://www.cnblogs.com/workformylove/p/3745037.html
Copyright © 2011-2022 走看看