【八中测试】跑马圈地(HihoCoder - 1042)

B - 跑马圈地

一觉醒来,小Hi穿越回了古代!由于破敌有功,大汗赏赐小Hi可以在敌人的草原上跑马圈地:一天之内骑马围住的草原以后就是小Hi的牧场。但是令小H头疼的是,敌人的草原上有一块臭水塘。小Hi不能骑马走进臭水塘里,并且即使小Hi的骑马路径围住了臭水塘,小Hi的牛马也不能在臭水塘里放牧。

为了更科学地圈地,小Hi对这个问题进行了简化和抽象:(1)敌人的草原是一块n×m的方格矩阵,(2)骑马的路径是沿着方格边缘的一段封闭折线,(3)臭水塘是矩阵中的一块矩形,(4)骑马的路径周长不超过L。小Hi想知道自己最大能圈住多大面积的草原(臭水塘的面积不计入在内)。

如图所示:图1是一条合法的路径;图2也是一条合法的路径,但是圈住的草原面积为0;图3不是合法的路径,因为没有封闭;图4也不是合法的路径,因为穿过了水塘。

Input

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

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

Output

小Hi最大能圈住的面积

Sample Input

4 4 8
1 3 1 3

Sample Output

3

【解析】

先说说正解吧,就是根据输入的周长L,从大到小地减小,并按从小到大的顺序来枚举长或宽,进而算出对应的宽或长,再根据不同的情况进行判断,直到找到最大值。
为方便理解,配有下图:
【八中测试】跑马圈地(HihoCoder - 1042)_第1张图片

【AC代码】

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
int n,m,L,l,r,t,b;
int re(int z,int y,int s,int x)
{
    int zmj=(y-z)*(x-s);
    int jq=max(min(y,r)-max(z,l),0)*max(min(x,b)-max(s,t),0);
    if(min(x,b)==b&&max(s,t)==t&&min(y,r)==r&&max(z,l)==l)
    return zmj-jq;
    if(min(x,b)==b&&max(s,t)==t&&x!=b&&s!=t)
    {
        if(((y-z)+(x-s))*2+2*(min(y,r)-max(z,l))<=L)
        return zmj-jq;
        return 0;
    }
    if(min(y,r)==r&&max(z,l)==l&&y!=r&&z!=l)
    {
        if(((y-z)+(x-s))*2+2*(min(x,b)-max(s,t))<=L)
        return zmj-jq;
        return 0;
    }
    return zmj-jq;
}
int main()
{
    scanf("%d %d %d",&n,&m,&L);
    scanf("%d %d %d %d",&l,&r,&t,&b);
    if(2*(n+m)<=L)
    {
        printf("%d\n",n*m-((r-l)*(b-t)));
        return 0;
    }
    int ans=0;
    for(;L>=4;L--)
    {
        for(int i=max(L/2-m,1);i<=n&&i<L/2;i++)
        {
            int j=L/2-i;
            ans=max(ans,re(0,j,0,i));
            ans=max(ans,re(0,j,n-i,n));
            ans=max(ans,re(m-j,m,0,i));
            ans=max(ans,re(m-j,m,n-i,n)); 
        }
    }
    printf("%d\n",ans);
}

你可能感兴趣的:(openjudge题库,刷题日志)