zoukankan      html  css  js  c++  java
  • 【BZOJ1720】[Usaco2006 Jan]Corral the Cows 奶牛围栏 双指针法

    【BZOJ1720】[Usaco2006 Jan]Corral the Cows 奶牛围栏

    Description

    Farmer John wishes to build a corral for his cows. Being finicky beasts, they demand that the corral be square and that the corral contain at least C (1 <= C <= 500) clover fields for afternoon treats. The corral's edges must be parallel to the X,Y axes. FJ's land contains a total of N (C <= N <= 500) clover fields, each a block of size 1 x 1 and located at with its lower left corner at integer X and Y coordinates each in the range 1..10,000. Sometimes more than one clover field grows at the same location; such a field would have its location appear twice (or more) in the input. A corral surrounds a clover field if the field is entirely located inside the corral's borders. Help FJ by telling him the side length of the smallest square containing C clover fields.

        约翰打算建一个围栏来圈养他的奶牛.作为最挑剔的兽类,奶牛们要求这个围栏必须是正方形的,而且围栏里至少要有C(1≤C≤500)个草场,来供应她们的午餐.
        约翰的土地上共有N(C≤N≤500)个草场,每个草场在一块lxl的方格内,而且这个方格的坐标不会超过10000.有时候,会有多个草场在同一个方格内,那他们的坐标就会相同.
        告诉约翰,最小的围栏的边长是多少?

    Input

    * Line 1: Two space-separated integers: C and N

    * Lines 2..N+1: Each line contains two space-separated integers that are the X,Y coordinates of a clover field.

        第1行输入C和N,接下来N行每行输入一对整数,表示一个草场所在方格的坐标

    Output

    * Line 1: A single line with a single integer that is length of one edge of the minimum size square that contains at least C clover fields.

        输入最小边长.

    Sample Input

    3 4
    1 2
    2 1
    4 1
    5 2

    Sample Output

    4
    OUTPUT DETAILS:
    Below is one 4x4 solution (C's show most of the corral's area); many
    others exist.

    |CCCC
    |CCCC
    |*CCC*
    |C*C*
    +------

    题解:二维双指针法的完美结合

    双指针法就是令l=1,从1到n枚举右指针r,然后始终保证[l,r]的区间是满足题目要求的区间,不满足就使l++,并每次用[l,r]更新答案(感觉就是简化的单调队列)

    如果坐标都是一维的,我们只用双指针法就能搞定,但是由于是二维的,所以我们要用两重双指针法(四指针法。。。)

    先二分答案,分别用双指针法维护纵坐标和横坐标,具体还是看代码吧~

     

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int n,m,nx,ny;
    struct field
    {
    	int x,y;
    }p[510];
    int rx[510],ry[510],s[510];
    bool cmp1(field a,field b)
    {
    	return a.x<b.x;
    }
    bool cmp2(field a,field b)
    {
    	return a.y<b.y;
    }
    bool solve(int ml)
    {
    	int i,a,b,c,d,sc,sd;
    	a=b=0;
    	memset(s,0,sizeof(s));
    	while(b<n&&rx[p[b+1].x]-rx[1]+1<=ml)	s[p[++b].y]++;
    	for(;b<=n;s[p[++b].y]++)
    	{
    		while(rx[p[b].x]-rx[p[a+1].x]+1>ml)	s[p[++a].y]--;
    		c=d=sc=sd=0;
    		while(d<ny&&ry[d+1]-ry[1]+1<=ml)	sd+=s[++d];
    		for(;d<=ny;sd+=s[++d])
    		{
    			while(ry[d]-ry[c+1]+1>ml)	sc+=s[++c];
    			if(sd-sc>=m)	return true;
    		}
    	}
    	return false;
    }
    int main()
    {
    	scanf("%d%d",&m,&n);
    	int i;
    	rx[0]=ry[0]=-1;
    	for(i=1;i<=n;i++)	scanf("%d%d",&p[i].x,&p[i].y);
    	sort(p+1,p+n+1,cmp2);
    	for(i=1;i<=n;i++)
    	{
    		if(p[i].y>ry[ny])	ry[++ny]=p[i].y;
    		p[i].y=ny;
    	}
    	sort(p+1,p+n+1,cmp1);
    	for(i=1;i<=n;i++)
    	{
    		if(p[i].x>rx[nx])	rx[++nx]=p[i].x;
    		p[i].x=nx;
    	}
    	int l=1,r=max(rx[nx],ry[ny]),mid;
    	while(l<r)
    	{
    		mid=l+r>>1;
    		if(solve(mid))	r=mid;
    		else	l=mid+1;
    	}
    	printf("%d",r);
    	return 0;
    }
  • 相关阅读:
    java运行时异常与一般异常有何异同?
    B+树原理及mysql的索引分析
    ibatis in的用法
    brython的问题
    限流算法的原理
    Java8的CompletionService使用与原理
    命令行相关快捷键
    Java8 异步编排类CompletableFuture
    分布式系统ID生成方案
    curl 命令简介
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6440899.html
Copyright © 2011-2022 走看看