Stars
Problem Description
There are N (1 ≤ N ≤ 400) stars in the sky. And each of them has a unique coordinate (x, y) (1 ≤ x, y ≤ N). Please calculate the minimum area of the rectangle (the edges of the rectangle must be parallel to the X, Y axes) that can cover at least K (1 ≤ K ≤ N) stars. The stars on the borders of the rectangle should not be counted, and the length of each rectangle’s edge should be an integer.
Input
Input may contain several test cases. The first line is a positive integer T (T ≤ 10), indicating the number of test cases below.
For each test cases, the first line contains two integers N, K, indicating the total number of the stars and the number of stars the rectangle should cover at least.
Each of the following N lines contains two integers x, y, indicating the coordinate of the stars.
Output
For each test case, output the answer on a single line.
Example Input
2 1 1 1 1 2 2 1 1 1 2
Example Output
1 2
Hint
Author
题目大意:
给你一个N*N大小的格子,然后给你N个星星的坐标,要求你选择一个矩形(平行于坐标轴),使得其包含的星星的个数(边缘也包含进去)大于等于k个.
问最小的矩形的面积是多大。
思路:
1、观察到X.Y的范围不大,所以我们可以看其作为一个400*400的01矩阵(1代表这个位子有星星),让我们去寻找一个可行范围的矩阵使得其中至少包含k个点。
2、那么我们O(N^2)枚举这个矩阵的上下界,然后O(N)去枚举这个矩阵的左端点,那么对应我们可以二分右端点,使得这个矩阵中至少包含K个点。
对于二分过程的查询,我们先行维护一个二维前缀和即可。
总时间复杂度O(N^3LogN),其实这个过程我们也可以尺取法来搞,将时间复杂度进一步的优化,问题给出了15S的时限,二分是可过的。
3、题目很俗套,将问题先转化成01矩阵问题,这个题就好解了。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int a[500][500];
int suma[500][500];
int n,kk;
void init()
{
memset(suma,0,sizeof(suma));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
suma[i][j]=suma[i][j-1]+a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
suma[j][i]=suma[j][i]+suma[j-1][i];
}
}
}
int query(int i,int j,int l,int r)
{
int sum=suma[j][r]-suma[j][l-1]-suma[i-1][r]+suma[i-1][l-1];
if(sum>=kk)return 1;
else return 0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&kk);
memset(a,0,sizeof(a));
for(int i=0;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
a[x][y]=1;
}
init();
int output=0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
for(int k=1;k<=n;k++)
{
int ans=-1;
int l=k;
int r=n;
while(r-l>=0)
{
int mid=(l+r)/2;
if(query(i,j,k,mid)==1)
{
ans=mid;
r=mid-1;
}
else l=mid+1;
}
if(ans!=-1)output=min(output,(j-i+1)*(ans-k+1));
}
}
}
printf("%d\n",output);
}
}