zoukankan      html  css  js  c++  java
  • AcWing 121 赶牛入圈 (二分+离散化)

    题目链接:https://www.acwing.com/problem/content/description/123/

    最朴素的做法是,暴力枚举每个正方形,维护前缀和判断是否符合条件,但是坐标范围太大
    注意到只有 500 个点,所以可以将坐标离散化一下

    正方形的边长显然满足二分性,所以二分边长即可

    离散化之后,每次枚举时,需要二分找出边长大于 (Mid) 的点的位置,注意边界处理等小细节

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 510;
    
    int C,N;
    int x[maxn], y[maxn], xx[maxn], yy[maxn], sum[maxn][maxn], cntx, cnty;
    
    bool Check(int Mid){
    	for(int i=1;i<=cntx;++i){
    		int lx = lower_bound(xx + 1, xx + 1 + cntx, xx[i] - Mid + 1) - xx;
    
    		for(int j=1;j<=cnty;++j){
    			int ly = lower_bound(yy + 1, yy + 1 + cnty, yy[j] - Mid + 1) - yy;
    
    			int tmp = sum[i][j] - sum[i][ly-1] - sum[lx-1][j] + sum[lx-1][ly-1];
    			if(tmp >= C){
    				return true;
    			}
    		}
    	}
    	return false;
    }
    
    int solve(){
    	int L = 1, R = 10000;
    	
    	while(L < R){
    		int Mid = (L + R) >> 1;
    		if(Check(Mid)){
    			R = Mid;
    		}else{
    			L = Mid + 1;
    		}
    	}
    	
    	return L;
    }
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
    	C = read(), N = read();
    	for(int i=1;i<=N;++i){
    		x[i] = read(), y[i] = read(); 
    		xx[i] = x[i], yy[i] = y[i];
    	}
    	
    	sort(xx + 1, xx + 1 + N);
    	cntx = unique(xx + 1, xx + 1 + N) - xx - 1;
    	
    	sort(yy + 1, yy + 1 + N);
    	cnty = unique(yy + 1, yy + 1 + N) - yy - 1;
    	
    	for(int i=1;i<=N;++i){
    		x[i] = lower_bound(xx + 1, xx + 1 + cntx, x[i]) - xx;
    		y[i] = lower_bound(yy + 1, yy + 1 + cnty, y[i]) - yy;
    		++sum[x[i]][y[i]];
    	}
    
    	for(int i=1;i<=cntx;++i){
    		for(int j=1;j<=cnty;++j){
    			sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + sum[i][j];
    		}
    	}
    	
    	printf("%d
    ",solve());
    	
    	return 0;
    }
    
  • 相关阅读:
    Java集合:HashMap
    Java线程池原理
    Linux常用命令
    分布式系统基本概念
    接口中的default方法(默认方法)
    正则表达式匹配+过滤
    Java Optional类
    mongo过期索引
    Java8函数式接口简介
    JS版微信6.0分享接口用法分析
  • 原文地址:https://www.cnblogs.com/tuchen/p/13935784.html
Copyright © 2011-2022 走看看