E

Description

 
epsfbox{p2689.eps}

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 (WH), 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 input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.

The first line of the input file contains three integer numbers NW, and H, separated by spaces. N ( 0$ le$N$ le$100) is the number of trees in the park. W and H ( 1$ le$WH$ le$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$ le$Xi$ le$W0$ le$Yi$ le$H) that represent coordinates of i-th tree. All trees are located at different coordinates.

Output 

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.

Write to the output file a single line with three integer numbers PQ, and L separated by spaces, where (PQ) 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.

Sample Input 

1

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

Sample Output 

4 3 4


Note: This is a sample input and output that corresponds to the park plan that is shown on the picture.

题意:给出一张二维图,上面有n个点,要求你找出一个最大的正方形,其中不能有点。

思路:解决这样的问题,当然是采用暴力的方法,可以这样,枚举这幅图的左区间 L 和右区间 R,如果这个区间之内没有点,那么就可以形成边长为min(R - L,h)的正方形了,如果有,那就从下至上考虑点的影响,每两个点之间就形成了上下区间,不过不要忘记最上面的点与w形成的区间和0与最下面的点形成的区间。

应该要注意到n的数据范围是100,而w,h的数据范围是10000,所以你在枚举左右区间时应该要想到绝对不可能采用h

同样的可以去考虑点对于区间选取的影响,每两个点之间形成一个区间,还要考虑最左边的和最右边的区间

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define REP(i,n) for(int i=1;i<=n;i++)
#define M(a)     memset(a,0,sizeof(a));
using namespace std;
const int maxn=100+20;
int n,w,h;
int idx[maxn];
struct node
{
    int x,y;
    bool operator < (const node & a) const
    {
        if(x!=a.x) return x<a.x;
        return y<a.y;
    }
} eve[maxn];

void Init()
{
    M(idx);
    scanf("%d%d%d",&n,&w,&h);
    eve[0].x=0,eve[0].y=0;
    idx[0]=0;
    idx[n+1]=h;  //idx的初始化很重要,是枚举的基础
    eve[n+1].x=w;
    eve[n+1].y=h;//同时也必须假设(0,0)和(w,h)各有一点
    REP(i,n)
    {
        scanf("%d%d",&eve[i].x,&eve[i].y);
        idx[i]=eve[i].y;
    }
}

void Work()
{
    int ansx=0,ansy=0,anslen=0;
    sort(eve+1,eve+n+1);
    sort(idx+1,idx+n+1);
    for(int i=0; i<=n; i++)
        for(int j=i+1; j<=n+1; j++)
        {
            int l=idx[i],r=idx[j],down=0,up,ww,hh;
            ww=r-l;
            for(int k=1; k<=n; k++)
            {
                if(eve[k].y>l&&eve[k].y<r)
                {
                    hh=eve[k].x-down;
                    if(anslen<min(ww,hh))
                    {
                        anslen=min(ww,hh);
                        ansx=l;
                        ansy=down;
                    }
                    down=eve[k].x;
                }
            }
            hh=w-down;
            if(anslen<min(ww,hh))
            {
                anslen=min(hh,ww);
                ansx=l;
                ansy=down;
            }
        }
    printf("%d %d %d
",ansy,ansx,anslen);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        Init();
        Work();
        if(T) puts("");
    }
    return 0;
}
View Code

自然也可以以上下界做枚举,不过一定要清楚输入给出的是x,y坐标,你用x,y却是把它看做行与列,完全不同啊

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=111;
struct node
{
    int x,y;
    bool operator < (const node & a) const
    {
        return y<a.y;
    }
} eve[maxn];

int idx[maxn];

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n,w,h;
        cin>>n>>w>>h;
        eve[0].x=0;idx[0]=0;
        eve[0].y=0;
        for(int i=1; i<=n; i++) {cin>>eve[i].y>>eve[i].x;idx[i]=eve[i].x;} //输入的y坐标是行,x坐标是列
        eve[n+1].x=h;idx[n+1]=h;
        eve[n+1].y=w;
        sort(eve+1,eve+n+1);
        sort(idx+1,idx+n+1);
        int maxlen=0,maxx=0,maxy=0;
        for(int i=0; i<=n+1; i++)
            for(int j=i+1; j<=n+1; j++)
            {
                int down=idx[i],up=idx[j],l=0,hi,wi;
                hi=up-down;
                //cout<<hi<<" "<<idx[i]<<" "<<idx[j]<<endl;
                for(int k=1;k<=n;k++)
                {
                    if(eve[k].x<=down||eve[k].x>=up) continue;
                    wi=eve[k].y-l;
                    if(maxlen<min(wi,hi))
                    {
                        maxlen=min(wi,hi);
                        maxx=down;
                        maxy=l;
                    }
                    l=eve[k].y;
                }
                wi=w-l;
                if(maxlen<min(wi,hi))
                {
                    maxlen=min(wi,hi);
                    maxx=down;
                    maxy=l;
                }
            }
        cout<<maxy<<" "<<maxx<<" "<<maxlen<<endl;
        if(T) puts("");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zsyacm666666/p/4928208.html