您的位置:首页 > 其它

FZU 2144 —— Shooting Game (贪心)

2013-12-27 13:57 295 查看
题意比较简单,就是给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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: