Cricket Field ——极大子矩行(坏点少)

题目来源:Gym100002C

Input file: cricket.in
Output file: cricket.out

Description

Once upon a time there was a greedy King who ordered his chief Architect to build a field for royal cricket inside his park. The King was so greedy, that he would not listen to his Architect’s proposals to build a field right in the park center with pleasant patterns of trees specially planted around and beautiful walks inside tree alleys for spectators. Instead, he ordered neither to cut nor to plant even a single tree in his park, but demanded to build the largest possible cricket field for his pleasure. If the Kind finds that the Architect has dared to touch even a single tree in his park or designed a smaller field that it was possible, then the Architect will loose his head. Moreover, he demanded his Architect to introduce at once a plan of the field with its exact location and size.
这里写图片描述

Your task is to help poor Architect to save his head, by writing a program that will find the maximum possible size of the cricket field and its location inside the park to satisfy King’s requirements.

The task is somewhat simplified by the fact, that King’s park has a rectangular shape and is situated on a flat ground. Moreover, park’s borders are perfectly aligned with North-South and East-West lines. At the same time, royal cricket is always played on a square field that is also aligned with North-South and East-West lines. Architect has already established a Cartesian coordinate system and has precisely measured the coordinates of every tree. This coordinate system is, of course, aligned with North-South and East-West lines. Southwestern corner of the park has coordinates (0, 0) and Northeastern corner of the part has coordinates (W, H), where W and H are the park width and height in feet respectively.

For this task, you may neglect the diameter of the trees. Trees cannot be inside the cricket field, but may be situated on its side. The cricket field may also touch park’s border, but shall not lie outside the park.

Input

The first line of the input file contains three integer numbers N, W, and H, separated by spaces. N (0 ≤ N ≤ 100) is the number of trees in the park. W and H (1 ≤ W, H ≤ 10000) are the park width and height in feet respectively.

Next N lines describe coordinates of trees in the park. Each line contains two integer numbers Xi and Yi separated by a space (0 ≤ Xi ≤ W, 0 ≤ Yi ≤ H) that represent coordinates of ith tree. All trees are located at different coordinates.

Output

Write to the output file a single line with three integer numbers P, Q, and L separated by spaces, where (P, Q) are coordinates of the cricket field Southwestern corner, and L is a length of its sides. If there are multiple possible field locations with a maximum size, then output any one.

cricket.in

7 10 7
3 2
4 2
7 0
7 3
4 5
2 4
1 7

cricket.out

4 3 4

代码

//============================================================================
// Name        : tree.cpp
// Author      : Qihan
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
//坏点较少,s^2写法
#include <bits/stdc++.h>
using namespace std;
#define pi acos(-1.0)
#define Lowbit(x) (x & (-x))
#define lson l,mid,rt << 1
#define rson mid + 1,r,rt << 1 | 1
#define inf 0x3f3f3f3f
#define maxn (8000 + 10)
typedef long long int LLI;
typedef pair<int,int> PII;


bool cmp(PII a,PII b) {
    if(a.first != b.first)  return a.first < b.first;
    return a.second < b.second;
}

bool cmp2(PII a,PII b) {
    return a.second < b.second;
}

PII a[maxn];
int main() {
//    freopen("/home/qihan/Documents/in","r",stdin);
//    freopen("cricket.in","r",stdin);
//    freopen("cricket.out","w",stdout);
    int n,x,y;
    while(~scanf("%d%d%d",&n,&x,&y)) {
        for(int i = 0; i < n; i ++) {
            scanf("%d%d",&a[i].first,&a[i].second);
        }
        a[n] = PII(0,0);
        a[n + 1] = PII(x,y);
        sort(a,a + n + 2,cmp);
        int ml = 0,mx = 0,my = 0;
        for(int i = 0; i < n + 2; i ++) {
            int u = y,d = 0;
            for(int j = i + 1; j < n + 2; j ++) {
                int ll = min(u - d,a[j].first - a[i].first);
                if(ll > ml) {
                    ml = ll;
                    mx = a[i].first;
                    my = d;
                }
                if(a[j].second > d && a[j].second < u) {
                    if(a[j].second > a[i].second)   u = a[j].second;
                    if(a[j].second < a[i].second)   d = a[j].second;
                    if(a[j].second == a[i].second)  break;
                }
            }
        }

        for(int i = n + 1; i >= 0; i --) {
            int u = y,d = 0;
            for(int j = i - 1; j >= 0; j --) {
                int ll = min(u - d,a[i].first - a[j].first);
                if(ll > ml) {
                    ml = ll;
                    mx = a[j].first;
                    my = d;
                }
                if(a[j].second > d && a[j].second < u) {
                    if(a[j].second > a[i].second)   u = a[j].second;
                    if(a[j].second < a[i].second)   d = a[j].second;
                    if(a[j].second == a[i].second)  break;
                }
            }
        }

        sort(a,a + n + 2,cmp2);
        for(int i = 0;i < n + 1;i ++){
            int ll = a[i + 1].second - a[i].second;
            ll = min(ll,x);
            if(ll > ml){
                ml = ll;
                mx = 0;
                my = a[i].second;
            }
        }
        printf("%d %d %d\n",mx,my,ml);
    }
    return 0;
}

参见:浅谈用极大化思想解决最大子矩形问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值