zoukankan      html  css  js  c++  java
  • CH6803 导弹防御塔

    背景

    Freda的城堡——
    “Freda,城堡外发现了一些入侵者!”
    “喵...刚刚探究完了城堡建设的方案数,我要歇一会儿嘛lala~”
    “可是入侵者已经接近城堡了呀!”
    “别担心,rainbow,你看呢,这是我刚设计的导弹防御系统的说~”
    “喂...别卖萌啊……”

    描述

    Freda的城堡遭受了M个入侵者的攻击!Freda控制着N座导弹防御塔,每座塔都有足够数量的导弹,但是每次只能发射一枚。在发射导弹时,导弹需要 T_1 秒才能从防御塔中射出,而在发射导弹后,发射这枚导弹的防御塔需要 T_2 分钟来冷却。
    所有导弹都有相同的匀速飞行速度V,并且会沿着距离最短的路径去打击目标。计算防御塔到目标的距离Distance时,你只需要计算水平距离,而忽略导弹飞行的高度。导弹在空中飞行的时间就是 (Distance/V) 分钟,导弹到达目标后可以立即将它击毁。
    现在,给出N座导弹防御塔的坐标,M个入侵者的坐标,T_1,T_2 和V。因为Freda的小伙伴Rainbow就要来拜访城堡了,你需要求出至少多少分钟才能击退所有的入侵者。

    输入格式

    第一行五个正整数N,M,T1,T2,V。
    接下来M行每行两个整数,代表入侵者的坐标。
    接下来N行每行两个整数,代表防御塔的坐标。

    输出格式

    输出一个实数,表示最少需要多少分钟才能击中所有的入侵者,四舍五入保留六位小数。

    样例输入

    3 3 30 20 1
    0 0
    0 50
    50 0
    50 50
    0 1000
    1000 0

    样例输出

    91.500000

    数据范围与约定

    • 对于40%的数据,N,M<=20.
      对于100%的数据, 1≤N≤50, 1≤M≤50,坐标绝对值不超过10000,T1,T2,V不超过2000.
            </article>
    

    题解

    答案满足单调性,可以二分答案,转化为判定问题。

    显然满足0要素和1要素。将导弹塔拆点,连边跑二分图匹配即可。注意这不是多重匹配,因为同一个导弹塔发射出的导弹不等价。

    时间复杂度(O(m*m*nmlog v))

    #include<bits/stdc++.h>
    #define rg register
    #define il inline
    #define co const
    template<class T>il T read(){
        rg T data=0,w=1;rg char ch=getchar();
        for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
        for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
        return data*w;
    }
    template<class T>il T read(rg T&x) {return x=read<T>();}
    typedef long long ll;
    using namespace std;
    typedef pair<int,int> pii;
    #define x first
    #define y second
    
    co int N=51,M=2501;
    co double eps=1e-8;
    int n,m,t,t2,V,f[M];
    double t1;
    bool v[M];
    pii a[N],b[N];
    pair<int,double> c[M];
    vector<int> e[N];
    il double dis(co pii&a,co pii&b){
    	return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));
    }
    bool dfs(int x){
    	for(unsigned i=0;i<e[x].size();++i){
    		int y=e[x][i];
    		if(v[y]) continue;
    		v[y]=1;
    		if(!f[y]||dfs(f[y])){
    			f[y]=x;
    			return 1;
    		}
    	}
    	return 0;
    }
    bool judge(double mid){
    	memset(f,0,sizeof f);
    	for(int i=1;i<=m;++i){
    		e[i].clear();
    		for(int j=1;j<=t;++j)
    			if(c[j].y+dis(a[i],b[c[j].x])/V<=mid)
    				e[i].push_back(j);
    	}
    	for(int i=1;i<=m;++i){
    		memset(v,0,sizeof v);
    		if(!dfs(i)) return 0;
    	}
    	return 1;
    }
    int main(){
    	read(n),read(m),read(t1),read(t2),read(V);
    	t=n*m,t1/=60;
    	for(int i=1;i<=m;++i) read(a[i].x),read(a[i].y);
    	for(int i=1;i<=n;++i) read(b[i].x),read(b[i].y);
    	for(int i=1;i<=m;++i)for(int j=1;j<=n;++j){
    		int k=(i-1)*n+j;
    		c[k].x=j,c[k].y=(i-1)*(t1+t2)+t1;
    	}
    	double l=t1,r=1e5;
    	while(l+eps<r){
    		double mid=(l+r)/2;
    		if(judge(mid)) r=mid;
    		else l=mid;
    	}
    	printf("%.6lf
    ",l);
    	return 0;
    }
    
  • 相关阅读:
    Day 20 初识面向对象
    Day 16 常用模块
    Day 15 正则表达式 re模块
    D14 模块 导入模块 开发目录规范
    Day 13 迭代器,生成器,内置函数
    Day 12 递归,二分算法,推导式,匿名函数
    Day 11 闭包函数.装饰器
    D10 函数(二) 嵌套,命名空间作用域
    D09 函数(一) 返回值,参数
    Day 07 Day08 字符编码与文件处理
  • 原文地址:https://www.cnblogs.com/autoint/p/10971508.html
Copyright © 2011-2022 走看看