Distant Galaxy   poj 3141

来源:互联网 发布:centos png 编辑:程序博客网 时间:2024/05/16 13:38
题意:  给出二维坐标上的n 个点 , 找出一个矩形 , 使得矩形边界上的点尽可能多次。

可以看出这是一个枚举的题目 , 但如果把矩形的每条边度枚举 , 那么肯定会超时 , 所有 , A这个题目的关键在于怎么来枚举 ,枚举那些东西?

通过观察 , 我们可以发现 , 除非所有点都在一行或一列上 , 否则 , 最优矩形的4条边都至少有一个点(一个角上的点同时算两条边的)。  但有不能枚举所有的边 , 因此我们考虑部分枚举 。

所以我们只枚举矩形的上下边界 , 上下边界最多只有 100*50 中可能 。

对于左右边界 , 我们也是通过枚举 , 这样之所以不同于全部枚举 , 在于 , 通过上下边界的枚举我们去除了很多没必要的枚举 。我们定义3个数组: on[i](当这条线是左边界时边界上的点) , on2[i](当这条线是右边界时边界上的点 , 和 on的区别是:on2 包含竖线和上下边界共有的点 , on 不包含) ,  ,xy[i](上下边界位于这条线左边的点数的数量) , 可以推出:
     xy[j] -xy[i] + on2[j] + on[i]  这就是当前这个矩形边界上的点。

代码:

#include
#include
#include
using namespace std;

struct point
{
    int x,y;
    booloperator < (const point &rhs) const
    {
       return x< rhs.x;
    }
};

const int maxn = 100 + 10;
struct point p[maxn];
int n , m , y[maxn] , on[maxn] , on2[maxn] ;
int xy[maxn];

int max(int x , int y)
{
    if(x >y)  return x;
    returny;
}

int solve()
{
    sort(p ,p+n);
    sort(y ,y+n);
    m = unique(y, y+n) - y;  //地址运算
    if(m <=2)  return n;
    int ans = 0, i , j;
    for(int a =0; a < m; a++)
       for(int b =a+1; b < m; b++)
       {
          int ymin =y[a] , ymax = y[b];

          int k =0;
          for( i = 0;i < n; i++)
          {
             if(i == 0 ||p[i].x != p[i-1].x)
             {
                k++;
                on[k] =on2[k] = 0;
                xy[k] =0;
                for(int f =0; f < n; f++)
                   if(p[f].y ==ymin || p[f].y == ymax)
                   {
                      if(p[f].x< p[i].x)  xy[k] += 1;
                   }
             }
             //if(p[i].y< ymin && p[i].y <ymax)   on[k]++;
             if(p[i].y>= ymin && p[i].y <= ymax)
             {
                if(p[i].y> ymin && p[i].y < ymax)  on[k]++ ,on2[k]++;
                elseon2[k]++;
             }
          }
          if(k <=2)  return n;
         
          int m =0;
          for( j = 1;j <= k; j++)
             for(i = 1; i<= k; i++)
             {
                if(j ==i)  continue ;
                int gy =on2[i] + on[j] + xy[i]-xy[j];
                ans =max(ans , gy);
             }
       }
       returnans;
}

int main()
{
    int kase =0;
   while(cin>>n && n)
    {
       for(int i =0; i < n; i++)
       {
         cin>>p[i].x>>p[i].y;
          y[i] =p[i].y;
       }
       printf("Case%d: %d\n" , ++kase , solve());
    }
    return0;
}
0 0
原创粉丝点击