Problem 85 : Counting rectangles

By counting carefully it can be seen that a rectangular grid measuring 3 by 2 contains eighteen rectangles:
Project Euler Problem 85 (C++和Python代码实现和解析)
Although there exists no rectangular grid that contains exactly two million rectangles, find the area of the grid with the nearest solution.

1. 欧拉项目第85道题 计数长方形

通过仔细的计数,可以看出一个3x2的矩形网格包含18个矩形:
Project Euler Problem 85 (C++和Python代码实现和解析)
虽然不存在包含精确200万个矩形的矩形网格,但是求最接近的解决方案的矩形网格的面积。

2. 求解分析

一个m x n的矩形网格包含多少个矩形呢? 首先,我们可以找到所有的小矩形i x j, 然后我们移动这个i x j矩形, 看在大矩形 m x n里有多少种移动方法,把所有i x j 矩形的移动方法累加求和,最后,我们可以统计得到矩形m x n可以包含的矩形数。

为了求解最接近2000000个矩形的矩形网格,我们使用枚举方法,最后找到最接近包含2000000个矩形的矩形面积。

3. C++ 代码实现

C++ 代码

#include <iostream>
#include <cassert>  // assert()
#include <cmath>    // abs()

using namespace std;

class PE0085
{
private:
    static const int m_max_rectangles = 2000000;

    int move_rectangle_ways(int i, int j, int m, int n);
    int get_num_of_rectangles(int m, int n);

public:
    int get_area_of_grid_with_nearest_solution();
};

int PE0085::move_rectangle_ways(int i, int j, int m, int n)
{
    int x_steps = m - i + 1;
    int y_steps = n - j + 1;

    return x_steps * y_steps;
}

int PE0085::get_num_of_rectangles(int m, int n)
{
    int numbers = 0;
    for (int i = 1; i < m + 1; i++)
    {
        for (int j = 1; j < n + 1; j++)
        {
            numbers += move_rectangle_ways(i, j, m, n);
        }
    }
    return numbers;
}

int PE0085::get_area_of_grid_with_nearest_solution()
{
    int min_diff = m_max_rectangles;
    int area = 0, numbers, diff;

    for (int m = 20; m <= 50; m++)
    {
        for (int n = 40; n <= 80; n++)
        {
            numbers = get_num_of_rectangles(m, n);
            if (numbers < m_max_rectangles + 10000 && 
                numbers > m_max_rectangles - 10000)
            {
                diff = abs(numbers - m_max_rectangles);
                if (diff < min_diff)
                {
                    area     = m * n;
                    min_diff = diff;
                }
            }
        }
    }
    return area;
}

int main()
{
    PE0085 pe0085;

    assert(18 == pe0085.get_num_of_rectangles(3, 2));

    cout << "The area of the grid with the nearest solution is ";
    cout << pe0085.get_area_of_grid_with_nearest_solution() << "." << endl;

    return 0;
}

4. Python 代码实现

Python 代码

def get_num_of_rectangles(m, n):
    numbers = 0
    for i in range(1, m+1):
        for j in range(1, n+1):
            numbers += move_rectangle_ways(i, j, m, n)                
    return numbers

def move_rectangle_ways(i, j, m, n):
    x_steps, y_steps = m-i+1, n-j+1
    return x_steps*y_steps

def get_area_of_grid_with_nearest_solution(max_rectangles):
    min_diff, area = max_rectangles, 0
    for m in range(20, 50):
        for n in range(40, 80):
            numbers = get_num_of_rectangles(m, n)
            if numbers < 21*10**5 and numbers>19*10**5:
                diff = abs(numbers - max_rectangles)
                if diff < min_diff: 
                    area, min_diff = m*n, diff
    return area
    
def main():
    assert 18 == get_num_of_rectangles(3, 2)
    
    print("The area of the grid with the nearest solution is %d." 
          % get_area_of_grid_with_nearest_solution(2*10**6))

if  __name__ == '__main__':
    main()

相关文章: