【题解】poj3179 二维前缀和+离散化+枚举

题目链接
学习了大佬题解,还是有点迷……有点不清醒,以后再看吧

#include<cstdio>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define pii pair<int,int>
#define PB(v) push_back(v)
#define MP(a,b) make_pair(a,b)
#define INF INT_MAX
const int N=1e3+10;
int c,n,sum[N][N];
vector<pii >p;
vector<int>X,Y;
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d%d",&c,&n);
    int x,y;
    _rep(i,1,n)scanf("%d%d",&x,&y),p.PB(MP(x,y)),X.PB(x),Y.PB(y);
    sort(p.begin(),p.end());
    sort(X.begin(),X.end());
    sort(Y.begin(),Y.end());
    X.erase(unique(X.begin(),X.end()),X.end());//去重
    Y.erase(unique(Y.begin(),Y.end()),Y.end());//去重
    x=X.size(),y=Y.size();
    X.PB(INF),Y.PB(INF);
    int pos=0;
    _rep(i,1,x)_rep(j,1,y)
    {
        sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
        while(pos<n&&p[pos].first==X[i-1]&&p[pos].second==Y[j-1])sum[i][j]++,pos++;//判断是否有草 
    }
    int ans=INF;
    _for(i,0,x)//枚举起点x坐标 
    {
        int i1=i+1;//终点x坐标
        int s=0;//边长
        int j=0;//起点y坐标
        int j1=1;//终点y坐标
        int v=sum[i1][j1]-sum[i][j1]-sum[i1][j]+sum[i][j];
        while(1)
        {
            while(v<c&&(i1<x||j1<y))
            {
                s=min(X[i1]-X[i],Y[j1]-Y[j]);
                while(X[i1]-X[i]<=s)i1++;
                while(Y[j1]-Y[j]<=s)j1++;
                v=sum[i1][j1]-sum[i][j1]-sum[i1][j]+sum[i][j];
            }
            if(v<c)break;//剪枝 
            ans=min(ans,s+1);
            if(++j==y)break;
            if(j1<=j)j1=j+1,s=0;
            else s-=Y[j]-Y[j-1];//边长减少 
            while(X[i1-1]-X[i]>s)i1--;
            v=sum[i1][j1]-sum[i][j1]-sum[i1][j]+sum[i][j];
        } 
    }
    printf("%d\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值