hihocoder#1042之跑马圈地

描述

一觉醒来,小Hi穿越回了古代!由于破敌有功,大汗赏赐小Hi可以在敌人的草原上跑马圈地:

一天之内骑马围住的草原以后就是小Hi的牧场。但是令小Hi头疼的是,敌人的草原上有一块

臭水塘。小Hi不能骑马走进臭水塘里,并且即使小Hi的骑马路径围住了臭水塘,小Hi的牛马

也不能在臭水塘里放牧。


为了更科学地圈地,小Hi对这个问题进行了简化和抽象:

(1)敌人的草原是一块n×m的方格矩阵

(2)骑马的路径是沿着方格边缘的一段封闭折线

(3)臭水塘是矩阵中的一块矩形

(4)骑马的路径周长不超过L

小Hi想知道自己最大能圈住多大面积的草原(臭水塘的面积不计入在内)。

如图所示:图1是一条合法的路径;图2也是一条合法的路径,但是圈住的草原面积为0;

图3不是合法的路径,因为没有封闭;图4也不是合法的路径,因为穿过了水塘。

输入

第一行3个整数:n, m, L (1 <= n, m <= 100, 1 <= L <= 400)

第二行4个整数:l, r, t, b (0 <= l < r <= m, 0 <= t < b <= n)表示水塘的左、右、上、下边界坐标。

输出

小Hi最大能圈住的面积

样例输入
4 4 8
1 3 1 3
样例输出
3

  
  
/*****************************************************************************************
 1、所有跑马的封闭曲线都可以化成矩形,除了横跨水塘的情形除外,横跨时封闭曲线实际为“凹”字型
 2、无论水塘在何处,都可以等效把水塘放在右下角,所以每次遍历矩形长宽可从左上角开始
 *****************************************************************************************/
#include
     
     
      
      
int main(void)
{
	int n, m, L, l, r, t, b, i, j, max = 0;
	scanf("%d%d%d%d%d%d%d", &n, &m, &L, &l, &r, &t, &b);
	if(L >= n * m)
		max = n * m - (r - l) * (b - t);
	else
	{
		for(i = 1; i < L / 2 && i <= n; i++)
			for(j = 1; j <= L / 2 - i && j <= m; j++)
			{
				if(l + r >= m && t + b >= n)//水塘实际就在右下角,不用转换
				{
					if(i <= t || j <= l)
						max = max > i * j ? max : i * j;
					else if(i > t && i <= b && j > l && j <= r)
						max = max > i * j - (i - t) * (j - l) ? max : i * j - (i - t) * (j - l);
					else if(i > t && i <= b && j > r && 2 * (i + j) + 2 * (i - t) <= L)//横跨
						max = max > i * j - (i - t) * (r - l) ? max : i * j - (i - t) * (r - l);
					else if(i > b && j > l && j <= r && 2 * (i + j) + 2 * (j - l) <= L)//横跨
						max = max > i * j - (b - t) * (j - l) ? max : i * j - (b - t) * (j - l);
					else if(i >= b && j >= r)
						max = max > i * j - (b - t) * (r - l) ? max : i * j - (b - t) * (r - l);
				}
				else if(l + r <= m && t + b <= n)//实际在左上角,转换到右下角
				{
					if(i <= n - b || j <= m - r)
						max = max > i * j ? max : i * (j);
					else if(i > n - b && i <= n - t && j > m - r && j <= m - l)
						max = max > i * j - (i - n + b) * (j - m + r) ? max : i * j - (i - n + b) * (j - m + r);
					else if(i > n - b && i <= n - t && j > m - l && 2 * (i + j) + 2 * (i - n + b) <= L)//横跨
						max = max > i * j - (i - n + b) * (r - l) ? max : i * j - (i - n + b) * (r - l);
					else if(i > n - t && j > m - r && j <= m - l && 2 * (i + j) + 2 * (j - m + r) <= L)//横跨
						max = max > i * j - (b - t) * (j - m + r) ? max : i * j - (b - t) * (j - m + r);
					else if(i >= n - t && j >= m - l)
						max = max > i * j - (b - t) * (r - l) ? max : i * j - (b - t) * (r - l);
				}
				else if(l + r <= m && t + b >= n)//实际在左下角,转换到右下角
				{
					if(i <= t || j <= m - r)
						max = max > i * j ? max : i * j;
					else if(i > t && i <= b && j > m - r && j <= m - l)
						max = max > i * j - (i - t) * (j - m + r) ? max : i * j - (i - t) * (j - m + r);
					else if(i > t && i <= b && j > m - l && 2 * (i + j) + 2 * (i - t) <= L)//横跨
						max = max > i * j - (i - t) * (r - l) ? max : i * j - (i - t) * (r - l);
					else if(i > b && j > m - r && j <= m - l && 2 * (i + j) + 2 * (j - m + r) <= L)//横跨
						max = max > i * j - (b - t) * (j - m + r) ? max : i * j - (b - t) * (j - m + r);
					else if(i >= b && j >= m - l)
						max = max > i * j - (b - t) * (r - l) ? max : i * j - (b - t) * (r - l);
				}
				else if(l + r >= m && t + b <= n)//实际在右上角,转换到右下角
				{
					if(i <= n - b || j <= l)
						max = max > i * j ? max : i * j;
					else if(i > n - b && i <= n - t && j > l && j <= r)
						max = max > i * j - (i - n + b) * (j - l) ? max : i * j - (i - n + b) * (j - l);
					else if(i > n - b && i <= n - t && j > r && 2 * (i + j) + 2 * (i - n + b) <= L)//横跨
						max = max > i * j - (i - n + b) * (r - l) ? max : i * j - (i - n + b) * (r - l);
					else if(i > n - t && j > l && j <= r && 2 * (i + j) + 2 * (j - l) <= L)//横跨
						max = max > i * j - (b - t) * (j - l) ? max : i * j - (b - t) * (j - l);
					else if(i >= n - t && j >= r)
						max = max > i * j - (b - t) * (r - l) ? max : i * j - (b - t) * (r - l);
				}
			}
	}
	printf("%d\n", max);
}

     
     
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值