FZU 2144 —— Shooting Game (贪心)

题意比较简单,就是给N个蚊子,主人公站在(0,0,0)这个位置上,然后N个蚊子有各自的起始点和移动方向,主人公可以在任意时间攻击,攻击的时候那些跟他距离不超过R的蚊子就算被击中,问最多能击中多少个以及最少要攻击几次。

做法就是对每个蚊子,求出它落在攻击范围内的时间段,列个关于时间t的距离不等式求解即可。

然后按照结束时间的顺序排序,贪心一下即可。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
struct Event{
    double st, ed;
    bool operator < (const Event& a)const{
        return ed<a.ed;
    }
}ev[100000];
int t, n, i, j, m, cnt;
double r, ax, ay, az, dx, dy, dz, a, b, c, d;
inline void getnum(int& x){
    char ch=getchar();
    bool mk=0;
    x = 0;
    while(ch<48 || ch>57){
        if(ch=='-')    mk=1;
        ch=getchar();
    }
    while(ch>=48 && ch<=57){
        x = x*10+ch-48;
        ch = getchar();
    }
    if(mk)    x=-x;
}
inline void getnum(double& x){
    int y;
    getnum(y);
    x = y*1.0;
}
int main(){
    getnum(t);
    for(int ct=1; ct<=t; ct++){
        m=0;
        getnum(n);
        getnum(r);
        while(n--){
            getnum(ax); getnum(ay); getnum(az);
            getnum(dx); getnum(dy); getnum(dz);
            a = dx*dx+dy*dy+dz*dz;
            b = 2*(ax*dx+ay*dy+az*dz);
            c = ax*ax+ay*ay+az*az-r*r;
            d = b*b-4*a*c;
            if(d<0)    continue;
            ev[m].st = (b*(-1)-sqrt(d))/(a*2);
            ev[m].ed = (b*(-1)+sqrt(d))/(a*2);
            if(ev[m].st<0 && ev[m].ed<0)    continue;//两个同时小于0表明不可能进入攻击范围
            m++;
        }
        printf("Case %d: %d ", ct, m);
        cnt=0;
        sort(ev, ev+m);
        for(i=0; i<m; i++){
            cnt++;
            a = ev[i].ed;
            j=i+1;
            while(j<m){
                if(ev[j].st<=a && ev[j].ed>=a){
                    j++;
                }
                else    break;
            }
            i = j-1;
        }
        printf("%d\n", cnt);
    }
    return 0;
}


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值