• 【DFS】Paintball(6-22)


    [UVA11853]Paintball

    算法入门经典第6章6-22(P175)

    题目大意:有一个1000*1000的正方形战场,西南角坐标(0,0),西北角坐标(0,1000),有n个敌人,每个敌人处在(xi,yi),攻击范围为ri,要避开他们的攻击范围,求从最左边出发的最北边出发点及右边的最北边到达点。

    试题分析:我们先判断是否能有方案,如何判断?将相交圆的圆心相连,看从交上边界的圆出发是否能到达与下边界相交的圆。然后再这个过程中如果看到与左/右边界相交的圆那么更新答案就好了。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<algorithm>
    using namespace std;
    
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    const int MAXN=2001;
    const int INF=999999;
    int N,M;
    vector<int> vec[MAXN];
    struct data{
    	double x,y,r;
    }cir[MAXN];
    bool vis[MAXN];
    double ansl,ansr;
    bool flag=false;
    
    double dis(int a,int b){
    	double x=cir[a].x-cir[b].x;
    	double y=cir[a].y-cir[b].y;
    	return sqrt(x*x+y*y);
    }
    bool DFS(int x){
    	if(vis[x]||flag) return false;
    	vis[x]=true;
    	if(cir[x].x-cir[x].r<=0){
    		flag=true;
    		return true;
    	}
    	if (cir[x].y<=cir[x].r) ansl=min(ansl,cir[x].x-sqrt(cir[x].r*cir[x].r-cir[x].y*cir[x].y));  
        if (cir[x].y+cir[x].r>=1000) {
        	double k=1000-cir[x].y;
    		ansr=min(ansr,cir[x].x-sqrt(cir[x].r*cir[x].r-k*k));
    	}
    	for(int i=0;i<vec[x].size();i++) DFS(vec[x][i]);
    	return false;
    }
    
    int main(){
    	while(scanf("%d",&N)!=EOF){
    		for(int i=1;i<=N;i++) vec[i].clear();
    		ansl=ansr=1000.0; flag=false;
    		for(int i=1;i<=N;i++){
    			scanf("%lf",&cir[i].y);
    			scanf("%lf",&cir[i].x);
    			scanf("%lf",&cir[i].r);
    		}
    		for(int i=1;i<N;i++){
    			for(int j=i+1;j<=N;j++){
    				if(dis(i,j)<=cir[i].r+cir[j].r){
    					vec[i].push_back(j);
    					vec[j].push_back(i);
    				}
    			}
    		}
    		memset(vis,false,sizeof(vis));
    		for(int i=1;i<=N;i++)
    			if(cir[i].r+cir[i].x>=1000)
    				if(DFS(i)) break;
    		if(flag) printf("IMPOSSIBLE
    ");  
            else printf("%.2f %.2f %.2f %.2f
    ",0.0,ansl,1000.0,ansr);
    	}
    }
  • 相关阅读:
    SGU180:Inversions(树状数组)
    Android布局中match_parent和fill_parent的差别
    上拉电阻和下拉电阻
    iOS应用性能调优的25个建议和技巧
    《拼音字母》 蓝桥杯复试试题
    构建轻量级的Table View注意事项[UIKit]
    Spark学习(一) 基本操作
    水滴状的自己定义视图,让您摆脱单调的Dialog
    【Scala】使用Option、Some、None,避免使用null
    基于tornado实现web camera
  • 原文地址:https://www.cnblogs.com/wxjor/p/7296202.html
Copyright © 2020-2023  润新知