uva 1382 - Distant Galaxy

 

题目连接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=91208#problem/G

 题意:  出平面上的n个点,找出一个矩形,使得边界上含有尽量多的点;输出最多的点数。

分析:

先枚举上下边界,然后从左到右扫,扫描一遍所有的点,计算l, on, on2数组,枚举右边界,维护on[i] - L[i]的最大值。

其中对于第i列,l[i]表示竖线左边位于上下边界的点数(不包括位于竖线i), on[i]表示竖线上位于上下边界之间的点数(和on2[i]的区别就是on[i]不统计位于上下边界的点数),

所以当给定左右边界i和j的话,矩形边界上的点数为l[j]+on2[j]+on[i]-l[i],当右边界j确定的时候,on[i]-left[i]要最大的;

特别的就是当n个点的横坐标或纵坐标小于等于2种时,那么这种情况ans = n。

 

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int  maxn=111;
int max(int a,int b)
{
    if(a>b) return a;
    else return b;
}
struct Point {
    int x, y;
    bool operator< (const Point& cmp) const{
        return x < cmp.x;
    }
}p[maxn];
int n,m,y[maxn],on[maxn],on2[maxn],l[maxn];
int sove()
{
     sort(p, p+n);
          sort(y, y+n);
           m = unique(y, y+n)-y;     //统计具有不同y坐标的点的个数
          if(m <= 2) return n;
          int ans = 0;
               for(int a=0;a<m;a++)
               {
                   for(int b=a+1;b<m;b++)
                   {
                       int k=0;
                       for(int i=0;i<n;i++)
                       {
                           if(i==0||p[i].x!=p[i-1].x)
                           {
                               k++;
                               on2[k]=on[k]=0;
                               l[k]=l[k-1]+on2[k-1]-on[k-1];
                            }
                           if(y[a]<=p[i].y&&p[i].y<=y[b])  on2[k]++;
                           if(y[a]<p[i].y&&p[i].y<y[b])  on[k]++;
                       }
                       if(k <= 2) return n;
                     int M = 0;
                   for(int j = 1; j <= k; j++) {
                    ans = max(ans, l[j]+on2[j]+M);
                    M = max(M, on[j]-l[j]);
                   }
                   }
               }
               return ans;
}
int main()
{
        int kase=1;
     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++, sove());
        }

    return 0;
}

 

转载于:https://www.cnblogs.com/fenhong/p/4924479.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值