解题报告 之 HDU5301 Buildings

解题报告 之 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 dimensionslocated inside. For each apartment, its dimensions can be different from each other. The numbermust be integers.Additionally, the apartments must completely cover the floor without onesquare 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 mosttestcases.For each testcase, only four space-separated integers,.

Output

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

Sample Input

2 3 2 23 3 1 1

Sample Output

12

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. 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 0x3f3f3f3fusing 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;}这道题重在思维,代码其实非常简单。一开始的调整动作是非常有必要的,也是此题精髓所在。

版权声明:本文为博主原创文章,未经博主允许不得转载。

人要有梦想,有了梦想才会努力奋斗,

解题报告 之 HDU5301 Buildings

相关文章:

你感兴趣的文章:

标签云: