uva1382 Distant Galaxy

来源:互联网 发布:mac 的idea提示快捷键 编辑:程序博客网 时间:2024/06/06 00:02

You are observing a distant galaxy using a telescope above the
Astronomy Tower, and you think that a rectangle drawn in that galaxy
whose edges are parallel to coordinate axes and contain maximum star
systems on its edges has a great deal to do with the mysteries of
universe. However you do not have the laptop with you, thus you have
written the coordinates of all star systems down on a piece of paper
and decide to work out the result later. Can you nish this task?
Input There are multiple test cases in the input le. Each test case
starts with one integer N , (1  N  100), the number of star systems
on the telescope. N lines follow, each line consists of two integers:
the X and Y coordinates of the K
-th planet system. The absolute value of any coordinate is no more than 10 9 , and you can assume that the planets are arbitrarily
distributed in the universe. N
= 0 indicates the end of input le and should not be processed by your program. Output For each test case, output the maximum value you have
found on a single line in the format as indicated in the sample
output.

直接枚举的话是O(n^5)【如果边枚举边维护可以做到O(n^4)】,所以考虑降低枚举量。
先把横纵坐标离散化,然后在x轴上枚举左右边界,先扫一遍算出每条y轴上的直线恰好在x轴上边界上的点的个数的前缀和sum,以及恰好在这条直线上的、被x轴上边界所包含的点的个数f【不计在x轴方向边界上的】。这样对于y轴上边界i..j,总点数为sum[j]-sum[i-1]+f[j]+f[i]。其中在顶点上的点只在sum中被计算一次,避免重复。这样扫描的时候维护f[i]-sum[i-1]的最大值,可以做到对于每个位置O(1)找到最优解,总复杂度为O(n^3)。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int oo=0x3f3f3f3f;int ax[110],ay[110],ox[110],oy[110],n,mx,my,sum[110],f[110];void init(){    int i;    for (i=1;i<=n;i++)    {        scanf("%d%d",&ax[i],&ay[i]);        ox[i]=ax[i];        oy[i]=ay[i];    }    sort(ox+1,ox+n+1);    mx=unique(ox+1,ox+n+1)-ox-1;    sort(oy+1,oy+n+1);    my=unique(oy+1,oy+n+1)-oy-1;    for (i=1;i<=n;i++)    {        ax[i]=lower_bound(ox+1,ox+mx+1,ax[i])-ox;        ay[i]=lower_bound(oy+1,oy+my+1,ay[i])-oy;    }}int solve(){    int x1,x2,i,j,ans=-oo,tem;    if (mx==1||my==1) return n;    for (x1=1;x1<=mx;x1++)      for (x2=1;x2<x1;x2++)      {        memset(sum,0,sizeof(sum));        memset(f,0,sizeof(f));        for (i=1;i<=n;i++)        {            if (ax[i]==x1||ax[i]==x2)              sum[ay[i]]++;            if (ax[i]<x1&&ax[i]>x2)              f[ay[i]]++;        }        for (i=2;i<=my;i++)          sum[i]+=sum[i-1];        for (i=1,tem=-oo;i<=my;i++)        {            ans=max(ans,sum[i]+f[i]+tem);            tem=max(tem,f[i]-sum[i-1]);        }      }    return ans;}int main(){    int K=0;    while (scanf("%d",&n)&&n)    {        init();        printf("Case %d: %d\n",++K,solve());    }}
0 0
原创粉丝点击