AtCoder 3597-Axis-Parallel Rectangle【二维前缀和+离散化】 难度:***

题意:

Problem Statement
We have N points in a two-dimensional plane.
The coordinates of the i-th point (1≤i≤N) are (xi,yi).
Let us consider a rectangle whose sides are parallel to the coordinate axes that contains K or more of the N points in its interior.
Here, points on the sides of the rectangle are considered to be in the interior.
Find the minimum possible area of such a rectangle.

Constraints
2≤K≤N≤50
−109≤xi,yi≤109(1≤i≤N)
xi≠xj(1≤i<j≤N)
yi≠yj(1≤i<j≤N)
All input values are integers. (Added at 21:50 JST)
Input
Input is given from Standard Input in the following format:

N K
x1 y1
:
xN yN
Output
Print the minimum possible area of a rectangle that satisfies the condition.

Sample Input 1
Copy
4 4
1 4
3 3
6 2
8 1
Sample Output 1
Copy
21
One rectangle that satisfies the condition with the minimum possible area has the following vertices: (1,1), (8,1), (1,4) and (8,4).
Its area is (8−1)×(4−1)=21.

Sample Input 2
Copy
4 2
0 0
1 1
2 2
3 3
Sample Output 2
Copy
1
Sample Input 3
Copy
4 3
-1000000000 -1000000000
1000000000 1000000000
-999999999 999999999
999999999 -999999999
Sample Output 3
Copy
3999999996000000001

题解:

问一张二维图中,能包含k个点的最小矩形面积是多少。像这种查询某个区域涵盖多少个点的题八成使用前缀和,但是这题的点群分布在−109≤xi,yi≤109(1≤i≤N)的范围上,直接前缀和会爆内存爆时间,注意观察一共只有50个点,所以我们可以通过离散化将分散的点聚集在50*50的区域中,然后再通过容斥原理进行前缀和的预处理,最后枚举矩形的左上角与右下角来寻找能包含至少k个点的矩形。

代码:

#include<stdio.h>
#include<stdlib.h>
struct node
{
	long long x,y;
	int a,b;
}point[55];
int incx(const void *a, const void *b)
{
    struct node m = *(struct node *)a;
    struct node n = *(struct node *)b;
    if(m.x<n.x) return -1;
    else return 1;
}
int incy(const void *a, const void *b)
{
    struct node m = *(struct node *)a;
    struct node n = *(struct node *)b;
    if(m.y<n.y) return -1;
    else return 1;
}
int main()
{
	int n,k,mp[55][55],xmax,ymax,temp;
	bool np[55][55];
	long long x[55],y[55],S,min=-1,xx[55],yy[55],Smax=-1;
	for(int i=0;i<55;i++)
	{
		for(int j=0;j<55;j++)
		{
			mp[i][j]=0;
			np[i][j]=false;
		}
	}
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++)scanf("%lld%lld",&point[i].x,&point[i].y);
	qsort(point,n,sizeof(struct node),incx);
	temp=0;
	for(int i=0;i<n;i++)
	{
		point[i].a=temp;
		xx[temp]=point[i].x;
		temp++;
	}
	qsort(point,n,sizeof(struct node),incy);
	temp=0;
	for(int i=0;i<n;i++)
	{
		point[i].b=temp;
		np[point[i].a][point[i].b]=true;
		yy[temp]=point[i].y;
		temp++;
	}
	if(np[0][0]==false)mp[0][0]=0;
	else mp[0][0]=1;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(i==0)mp[i][j]=mp[i][j-1]+np[i][j];
			else if(j==0)mp[i][j]=mp[i-1][j]+np[i][j];
			else mp[i][j]=mp[i-1][j]+mp[i][j-1]-mp[i-1][j-1]+np[i][j];
		}
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			for(int p=i+1;p<n;p++)
			{
				for(int q=j+1;q<n;q++)
				{
					int sum;
					if(i==0)sum=mp[p][q]-mp[p][j-1];
					else if(j==0)sum=mp[p][q]-mp[i-1][q];
					else sum=mp[p][q]-mp[i-1][q]-mp[p][j-1]+mp[i-1][j-1];
					if(sum>=k)
					{
						if((xx[p]-xx[i])*(yy[q]-yy[j])<=Smax||Smax<0)Smax=(xx[p]-xx[i])*(yy[q]-yy[j]);
					}
				}
			}
		}
	}
	printf("%lld\n",Smax);
}

猜你喜欢

转载自blog.csdn.net/weixin_42921101/article/details/104341435
今日推荐