码迷,mamicode.com
首页 > 其他好文 > 详细

解题报告 之 HDU5301 Buildings

时间:2015-08-19 01:59:54      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:acm   多校   思维   hdu5301   

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


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

解题报告 之 HDU5301 Buildings

标签:acm   多校   思维   hdu5301   

原文地址:http://blog.csdn.net/maxichu/article/details/47763757

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!