• 【贪心 + 模拟】UVA10382 Watering Grass


    感觉这种位置指针跳来跳去的题好难写对,记录一下套路。

    传送门:https://www.luogu.com.cn/problem/UVA10382

    思路比较简单:处理一下每个装置的有效左右区间(显然半径刚好能够到达的点是临界),然后从左到右贪心地选取装置:具体来说就是维护一个前缀的控制区域(只需维护最右的端点),控制区域内是一个装置左边界的集合,我们从这个集合出发考察右边界的最大值,得到最大值后更新控制区域,如此下去即可。

    while(cur<l){ // 只要控制区域的最右没有到达草坪的最右,就继续更新
    	double np=cur; // new point 记录控制区域右端点。
    	for(; p<=n && q[p].x<=cur; p++) np=max(np, q[p].y); // p 维护前缀点集的装置编号,np 从中更新最右点。
    	
    	if(np==cur && cur<l){ // 如果np没有得到更新而且无法到达终点,无解。
    		ok=false;
    		break;
    	}
    	
    	res++; // 更新答案
    	cur=np; // 更新控制区域
    }
    
    #pragma GCC optimize("O3")
    #include<bits/stdc++.h>
    using namespace std;
    #define endl '
    '
    #define debug(x) cerr << #x << ": " << x << endl
    #define pb(a) push_back(a)
    #define set0(a) memset(a,0,sizeof(a))
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define dwn(i,a,b) for(int i=(a);i>=(b);i--)
    #define ceil(a,b) (a+(b-1))/b
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define ll_INF 0x7f7f7f7f7f7f7f7f
    typedef long long ll;
    typedef pair<int,int> PII;
    typedef pair<double,double> PDD;
    
    #define x first
    #define y second
    
    inline void read(int &x) {
        int s=0;x=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
        x*=s;
    }
    
    const int N=1e4+5;
    
    int n, l;
    double w;
    
    PII e[N];
    PDD q[N];
    
    int main(){
    	while(cin>>n>>l>>w && n){
    		rep(i,1,n){
    			int a, b; read(a), read(b);
    			e[i]={b, a}; // radius and position
    		}
    		sort(e+1, e+1+n);
    		
    		rep(i,1,n){
    			double o=e[i].y, r;
    			if(e[i].x<=w/2) r=0;
    			else r=sqrt(1.0*e[i].x*e[i].x-(1.0*w/2)*(w/2));
    			double L=max((double)0, o-r), R=min((double)l, o+r);
    			q[i]={L, R};	
    		}
    		
    		sort(q+1, q+1+n);
    		
    		int res=0, p=1;
    		bool ok=true;
    		double cur=0;
    		
    		while(cur<l){ // 只要控制区域的最右没有到达草坪的最右,就继续更新
    			double np=cur; // new point 记录控制区域右端点。
    			for(; p<=n && q[p].x<=cur; p++) np=max(np, q[p].y); // p 维护前缀点集的装置编号,np 从中更新最右点。
    			
    			if(np==cur && cur<l){ // 如果np没有得到更新而且无法到达终点,无解。
    				ok=false;
    				break;
    			}
    			
    			res++; // 更新答案
    			cur=np; // 更新控制区域
    		}
    		
    		if(ok) cout<<res<<endl;
    		else puts("-1");
    	}
    	
        return 0;
    }
    
  • 相关阅读:
    正交实验
    边界值
    等价类划分概述
    测试用例编写
    java基础复习(四)
    easyui datagrid 搜索功能
    一段代码把网站变成灰白色
    PHP 获取二维数组中某个key的集合
    如何使用Mobile_Detect来判断访问网站的设备:安卓,平板,电脑
    easyui validatebox 验证类型
  • 原文地址:https://www.cnblogs.com/Tenshi/p/14998311.html
Copyright © 2020-2023  润新知