前言:
本题为作业
题目描述
查看题目信息
给出平面上的n个点,请找出一个边与坐标轴平行的矩形,使得它的边界上有尽量多的点
输入格式
第一行一个整数n,为平面内点的个数。
第2~n+1行每行两个整数,为点的横、纵坐标。
输出格式
只有一个数,为所取矩形边界上能包含尽量多的点的个数。
样例输入
10 2 3 9 2 7 4 3 4 5 7 1 5 10 4 10 6 11 4 4 6
样例输出
7
问题提示
【数据范围】
对于40%的数据,n<=30
对于100%的数据,n<=300,各点的横、纵坐标在1~100范围内
如果给定的某些点具有相同的横纵坐标,这些重复的点算1个点
解题思路
枚举每一个矩形边上的点数量,最后求出最大值
整个矩形外圈点的个数减矩形内圈点的个数就是:
s[x][y]意思是(1,1)到(x,y)矩形区域内的点的个数
注:本题需要四重循环
AC完整代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e2+5;
int a[N][N],s[N][N];//s[i][j]从(1,1)到(i,j)矩形区域内的点的个数
int n;
int sm(int xa,int ya,int xb,int yb)
{
return s[xb][yb]-s[xb][ya-1]-s[xa-1][yb]+s[xa-1][ya-1];
}
int main()
{
int x,y;
int maxs=1;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x>>y;
a[x][y]=1;
}
//维护前缀和
for(int i=1;i<=100;i++)
{
for(int j=1;j<=100;j++)
{
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
}
}
//遍历所有的子矩形
for(int xa=1;xa<=100;xa++)
{
for(int ya=1;ya<=100;ya++)
{//枚举矩形的左上角坐标(xa,ya)
for(int xb=xa+1;xb<=100;xb++)
{
for(int yb=ya+1;yb<=100;yb++)
{//枚举矩形的右下角坐标 (xb,yb)
//求该矩形的边界上的点的数量
//(xa,ya)(xb,yb) (xa+1,ya+1)(xb-1,yb-1)
int su=sm(xa,ya,xb,yb)-sm(xa+1,ya+1,xb-1,yb-1);//(a,b)(a,b) (a+1,b+1)(a-1)(b-1)
maxs=max(maxs,s);
}
}
}
}
cout<<maxs;
return 0;
}