您的位置:首页 > 产品设计 > UI/UE

解题报告 之 HDU5301 Buildings

2015-08-19 00:22 295 查看


解题报告 之 HDU5301 Buildings

Description

Your current task is to make a ground plan for a residential building located in HZXJHS. So you must determine a way to split the floor building with walls to make apartments in the shape of a rectangle. Each built wall must be paralled
to the building's sides.

The floor is represented in the ground plan as a large rectangle with dimensions





,
where each apartment is a smaller rectangle with dimensions





located
inside. For each apartment, its dimensions can be different from each other. The number

and

must
be integers.

Additionally, the apartments must completely cover the floor without one





square
located on









.
The apartments must not intersect, but they can touch.

For this example, this is a sample of





























.



To prevent darkness indoors, the apartments must have windows. Therefore, each apartment must share its at least one side with the edge of the rectangle representing the floor so it is possible to place a window.

Your boss XXY wants to minimize the maximum areas of all apartments, now it's your turn to tell him the answer.


Input

There are at most









testcases.

For each testcase, only four space-separated integers,







































































.


Output

For each testcase, print only one interger, representing the answer.


Sample Input

2 3 2 2
3 3 1 1




Sample Output

1
2


Hint

Case 1 : 
          

 You can split the floor into five 





 apartments. The answer is 1. Case 2: 
          

 You can split the floor into three 





 apartments and two 





 apartments. The answer is 2. 
          

 If you want to split the floor into eight 





 apartments, it will be unacceptable because the apartment located on (2,2) can't have windows.


题目大意:给一个n*m的棋盘,有一个格子(x,y)已经涂黑,其他格子必须用大小不同的矩形地砖铺满,地砖之间不能重叠,每一块地砖必须至少有一边挨着墙壁(比如图三中的紫色地砖就不符合要求)。要使得所用的最大地砖面积最小,问这个面积是多少?

分析:求最大值的最小值,第一反应是二分。但是这道题二分的条件并不好验证(因为给定地砖最大值无法判断是否能构造)。所以其实这道题不是二分。我们来看看,首先明确每块砖靠墙的那条边长度一定为1。因为如果不为1的话我们大可以拆成两块来用,则问题就转换为了求长度。

首先我们处理一下棋盘,旋转使得水平方向更长,这样有助于合并情况。那么,比如对于一个30行5列的棋盘,我们旋转为5行30列的棋盘。
很容易注意到最终答案一定是大于等于宽的一半的(即ans>=3)。另外根据黑块的位置,我们可以考虑从上下左右四个方向来填补,如果从上下来填补,那么答案先取max(width/2 , max( x-1, n-x ) )。如果从左右来填,那么答案取max(width/2 , min(y-1,m-y)
)。很多人会疑惑这里为什么前面是max( x-1, n-x )而后面是min(y-1,m-y)。因为从左右填的话,比如选择从右边到达黑框更短,剩下的左边可以用上下来填补,并不需要真的从左边来填。而对于上下来说,却不能这样做(因为上下被调整为更短的边了)。-----
看图



(图中白色框住的部分不需要从左边铺,而可以直接从上下逐个格子来补)

那么到底是从左右铺还是上下铺呢?最终表达式就是max(
floor( width / 2 ) , min( max( x-1, n-x ) , min(
y-1 , m-y ) ) )

上代码:
#include <iostream>
#include<algorithm>

#define INF 0x3f3f3f3f
using namespace std;

int main()
{

	int n, m, x, y, ans;
	while(~scanf( "%d%d%d%d", &n, &m, &x, &y ))
	{
		if(n>m) swap( n, m ), swap( x, y );//调整,非常重要,注意x和n要一起旋转
		
		if(n == m && n & 1 && x == y && x == (n + 1) / 2)
			ans = x - 1;
		else      
		{
			int m1 = min( y, m - y + 1 );  
			int m2 = max( x - 1, n - x );  
			ans = min( m1, m2 ); 
			ans = max( ans, (n + 1) / 2 );
		}
		printf( "%d\n", ans );
	}
	return 0;
}
这道题重在思维,代码其实非常简单。一开始的调整动作是非常有必要的,也是此题精髓所在。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: