题意:
给出二维坐标上的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;
bool operator < (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;
return y;
}
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]++;
else on2[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);
}
}
return ans;
}
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());
}
return 0;
}
可以看出这是一个枚举的题目 , 但如果把矩形的每条边度枚举 , 那么肯定会超时 , 所有 , A这个题目的关键在于怎么来枚举 , 枚举那些东西?
通过观察 , 我们可以发现 , 除非所有点都在一行或一列上 , 否则 , 最优矩形的4条边都至少有一个点(一个角上的点同时算两条边的) 。
所以我们只枚举矩形的上下边界 , 上下边界最多只有 100*50 中可能 。
对于左右边界 , 我们也是通过枚举 , 这样之所以不同于全部枚举 , 在于 , 通过上下边界的枚举我们去除了很多没必要的枚举 。 我们定义3个数组: on[i](当这条线是左边界时边界上的点) , on2[i](当这条线是右边界时边界上的点 , 和 on 的区别是:on2 包含竖线和上下边界共有的点 , on 不包含) ,
代码:
#include
#include
#include
using namespace std;
struct point
{
};
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)
{
}
int solve()
{
}
int main()
{
}