HDU 5128 The E-pang Palace (暴力+几何思维 详解)

E-pang Palace was built in Qin dynasty by Emperor Qin Shihuang in Xianyang, Shanxi Province. It was the largest palace ever built by human. It was so large and so magnificent that after many years of construction, it still was not completed. Building the great wall, E-pang Palace and Qin Shihuang's tomb cost so much labor and human lives that people rose to fight against Qin Shihuang's regime. 

Xiang Yu and Liu Bang were two rebel leaders at that time. Liu Bang captured Xianyang -- the capital of Qin. Xiang Yu was very angry about this, and he commanded his army to march to Xianyang. Xiang Yu was the bravest and the strongest warrior at that time, and his army was much more than Liu Bang's. So Liu Bang was frighten and retreated from Xianyang, leaving all treasures in the grand E-pang Palace untouched. When Xiang Yu took Xianyang, he burned E-pang Palce. The fire lasted for more than three months, renouncing the end of Qin dynasty. 

Several years later, Liu Bang defeated Xiangyu and became the first emperor of Han dynasty. He went back to E-pang Palace but saw only some pillars left. Zhang Liang and Xiao He were Liu Bang's two most important ministers, so Liu Bang wanted to give them some awards. Liu Bang told them: "You guys can make two rectangular fences in E-pang Palace, then the land inside the fences will belongs to you. But the corners of the rectangles must be the pillars left on the ground, and two fences can't cross or touch each other." 

To simplify the problem, E-pang Palace can be consider as a plane, and pillars can be considered as points on the plane. The fences you make are rectangles, and you MUST make two rectangles. Please note that the rectangles you make must be parallel to the coordinate axes. 

The figures below shows 3 situations which are not qualified(Thick dots stands for pillars): 


Zhang Liang and Xiao He wanted the total area of their land in E-pang Palace to be maximum. Please bring your computer and go back to Han dynasty to help them so that you may change the history.
Input
There are no more than 15 test case. 

For each test case: 

The first line is an integer N, meaning that there are N pillars left in E-pang Palace(4 <=N <= 30). 

Then N lines follow. Each line contains two integers x and y (0 <= x,y <= 200), indicating a pillar's coordinate. No two pillars has the same coordinate. 

The input ends by N = 0.
Output
For each test case, print the maximum total area of land Zhang Liang and Xiao He could get. If it was impossible for them to build two qualified fences, print "imp".
Sample Input
8
0 0
1 0
0 1
1 1
0 2
1 2
0 3
1 3
8
0 0
2 0
0 2
2 2
1 2
3 2
1 3
3 3
0
Sample Output
2
imp

题意:

刘邦,项羽大战之后好像是把阿旁宫给毁了,现在阿旁宫就剩了一些柱子。

刘邦为了奖励他的两员大将 张良和萧何,就给他俩说,你看这阿房宫这么大,分点地给你们吧。你们一人圈一块地,这块地必须是矩形的,而且你们俩的地不能有交叉,连边都不能碰到,圈好了地就是你们的。

张良和萧何听了高兴啊,当然是能圈多大就圈多大,但是他俩关系好啊,舍小家为大家,圈的总面积最大才罢休。

思路:

输入的数据是整数点,点的数量最多是30,直接暴力不会超时。

做法就是开一个二维数组,bool类型,存下标对应的点是不是存在。

然后从左上到右下遍历找是否存在矩形(四个点依次确定是否存在),把找到的矩形都存起来,按照固定的四个点的顺序存四个点。

所有矩形存下来之后两两比较是否满足条件,一种是完全相离,一种是完全包含(坑点)

判断方法:


如上图,左上角是下标靠前的矩形(存的时候就是左上到右下的顺序),另一个和它相离(满足条件)的矩形出现的情况有上面三种

如果按照顺序存了矩形的坐标,那么只需比较第二个矩形的坐标0和第一个矩形的坐标2就行了

关系式是0的x坐标大于2的x坐标 或者 0的y坐标大于2的y坐标

然后算两个矩形的面积找个最大值。

完全包含的情况加个判断,但这时候算的是外面那个大的矩形的面积。


算了一下,如果是5*6矩阵样子的点,行和列找俩点确定矩形,一共有C(6,2)*C(5,2)=150个矩形。

每两个矩形判断一下,大约150*149/2的复杂度。不会超,这是最坏情况。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <math.h>

using namespace std;
typedef long long LL;
bool a[205][205];
struct jx{
    LL x[4],y[4];
}data[50000];
int main()
{
    int n,x,y;
    while(scanf("%d",&n)&&n)
    {
        memset(a,false,sizeof(a));
        while(n--)
        {
            scanf("%d%d",&x,&y);
            a[x][y]=true;
        }

        int num=0;

        for(int i=0;i<202;i++)
            for(int j=0;j<202;j++)
        {
            if(a[i][j])
            {
                for(int k=j+1;k<202;k++)
                {
                    if(a[i][k])
                    {

                        for(int l=i+1;l<202;l++)
                        {
                            if(a[l][k])
                            {
                                if(a[l][j])
                                {
                                    data[num].x[0]=i;data[num].y[0]=j;
                                    data[num].x[1]=i;data[num].y[1]=k;
                                    data[num].x[2]=l;data[num].y[2]=k;
                                    data[num].x[3]=l;data[num].y[3]=j;
                                    num++;

                                }
                            }
                        }
                    }
                }
            }
        }
        //cout<<"num="<<num<<endl;

      /*  for(int i=0;i<num;i++)
            for(int j=0;j<4;j++)
            cout<<data[i].x[j]<<" ";*/

        LL maxn=0;
       for(int i=0;i<num;i++)
            for(int j=i+1;j<num;j++)
       {
           if(data[j].x[0]>data[i].x[2]||data[j].y[0]>data[i].y[2])
           {
               LL s1=(data[i].x[2]-data[i].x[0])*(data[i].y[2]-data[i].y[0]);
               LL s2=(data[j].x[2]-data[j].x[0])*(data[j].y[2]-data[j].y[0]);
               LL answer=s1+s2;
               //cout<<"ans"<<answer<<endl;
               if(answer>maxn)
                maxn=answer;
           }
           if(data[i].x[0]<data[j].x[0]&&data[i].y[0]<data[j].y[0]&&data[i].x[2]>data[j].x[2]&&data[i].y[2]>data[j].y[2])
           {
               LL s1=(data[i].x[2]-data[i].x[0])*(data[i].y[2]-data[i].y[0]);
               
               LL answer=s1;
               //cout<<"ans"<<answer<<endl;
               if(answer>maxn)
                maxn=answer;
           }
       }



        if(maxn==0)
            printf("imp\n");
        else
            printf("%lld\n",maxn);


    }
    return 0;
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值