SDUT 3254 Stars【二维前缀和+二分+暴力枚举】

142 篇文章 0 订阅
111 篇文章 0 订阅

Stars

Time Limit: 15000MS  Memory Limit: 65536KB
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
 “浪潮杯”山东省第六届ACM大学生程序设计竞赛

题目大意:

给你一个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);
    }
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值