Problem 85 : Counting rectangles
By counting carefully it can be seen that a rectangular grid measuring 3 by 2 contains eighteen rectangles:
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个矩形:
虽然不存在包含精确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()