zoukankan      html  css  js  c++  java
  • UVA 11853 Paintball

    https://vjudge.net/problem/UVA-11853

    题目

    一堆人玩水弹(也许是吧),知道他们的坐标和攻击范围,问你从西边到东边能否不被水弹砸。找出西边进入的位置和东边出去的位置。

    $nleqslant1000$

    题解

    最近一直在写水题……为了看看每道题使用的时间,还写了个计时器,但是这题用的时间太长了……

    WA了一次,计算上罚时就是2小时了= =

    坐标没看清楚,样例都纠结了半小时,然后少考虑了一种情况

    按照紫书上的题解:

    看有没有一条把这块地分成左右两边的路……

    如果有就无解,没有就有解

    然后从北边开始便利,找到与左右边界相交的最南边的坐标

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    #define REP(i,x,y) for(register int i=(x); i<(y); i++)
    #define REPE(i,x,y) for(register int i=(x); i<=(y); i++)
    #ifdef sahdsg
    #define DBG(a,...) printf(a, ##__VA_ARGS__)
    #else
    #define DBG(a,...) (void)0
    #endif
    
    #define MAXN 1007
    int n;
    struct yuan {
    	double r,x,y;
    } arr[MAXN];
    
    inline bool conn(int i, int j) {
    	double rr = arr[i].r+arr[j].r;
    	double dx = arr[i].x-arr[j].x;
    	double dy = arr[i].y-arr[j].y;
    	rr*=rr;
    	dx*=dx;
    	dy*=dy;
    	return dx+dy<=rr;
    }
    bool vis[MAXN];
    
    inline bool bfs1(int i) {
    	queue<int> q;
    	q.push(i);
    	vis[i]=true;
    	while(!q.empty()) {
    		int now = q.front(); q.pop();
    		if(arr[now].y-arr[now].r<=0) return true;
    		REP(i,0,n) {
    			if(!vis[i] && conn(now,i)) {
    				q.push(i);
    				vis[i]=true;
    			}
    		}
    	}
    	return false;
    }
    
    double ans1, ans2;
    bool   has1, has2;
    
    inline void bfs2(int i) {
    	queue<int> q;
    	q.push(i);
    	while(!q.empty()) {
    		int now = q.front(); q.pop();
    		if(arr[now].x-arr[now].r<=0) {
    			ans1=min(ans1,arr[now].y-sqrt(arr[now].r*arr[now].r-arr[now].x*arr[now].x));
    		}
    		if(arr[now].x+arr[now].r>=1000) {
    			double dx=1000.0-arr[now].x;
    			ans2=min(ans2,arr[now].y-sqrt(arr[now].r*arr[now].r-dx*dx));
    		}
    		REP(i,0,n) {
    			if(!vis[i] && conn(now,i)) {
    				q.push(i);
    				vis[i]=true;
    			}
    		}
    	}
    }
    
    
    int main() {
    	#ifdef sahdsg
    	freopen("in.txt","r",stdin);
    	#endif
    	
    	while(~scanf("%d", &n)) {
    		REP(i,0,n) {
    			double &x=arr[i].x, &y=arr[i].y, &r=arr[i].r;
    			scanf("%lf%lf%lf", &x, &y, &r);
    		}
    		bool f=true;
    		memset(vis,0,sizeof vis);
    		REP(i,0,n) {
    			double &x=arr[i].x, &y=arr[i].y, &r=arr[i].r;
    			if(!vis[i] && y+r>=1000) {
    				if(bfs1(i)) {
    					f=false;
    					break;
    				}
    			}
    		}
    		if(!f) {
    			puts("IMPOSSIBLE");
    		} else {
    			memset(vis,0,sizeof vis);
    			ans1=ans2=1000;
    			has1=has2=false;
    			REP(i,0,n) {
    				double &x=arr[i].x, &y=arr[i].y, &r=arr[i].r;
    				if(!vis[i] && y+r>=1000) {
    					bfs2(i);
    				}
    			}
    			printf("0.00 %.2lf 1000.00 %.2lf
    ", ans1, ans2);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    《火影忍者:究级风暴》渲染技术究极解析!
    动态数组和内置数组转换范例
    固定视角
    旋转
    时间间隔操作
    编辑器的一些批处理脚本
    访问GUItexture
    血槽制作
    动画循环播放
    软件测试修炼之道之——重现问题(上)
  • 原文地址:https://www.cnblogs.com/sahdsg/p/10422278.html
Copyright © 2011-2022 走看看