15145641

  主要思路:求出蚊子到达球的时间区间(用方程得解),对区间做一个贪心的选择,选择尽可能多的区间有交集的区间段(结构体排序即可),然后计数.

#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define maxn 100025
int n, m, x,y;
ll r;
int t;
struct point
{
    ll x, y, z,dx,dy,dz;
    point(ll x = 0, ll y = 0, ll z = 0, ll dx = 0, ll dy = 0, ll dz = 0) :x(x), y(y), z(z) {}
} a[maxn];
ll dis(point p1,point p2)
{
    return (p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y) + (p1.z - p2.z)*(p1.z - p2.z);
}
int b[maxn];
double c[maxn];
struct node
{
    double lf, ri;
} lr[maxn];
bool cmp(node a, node b)
{
    return a.lf < b.lf;
}
int main()
{
    int cas = 1;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d%ld", &n, &r);
        int k = 0;
        point a;
        for (int i = 0; i < n; i++)
        {
            scanf("%I64d%I64d%I64d%I64d%I64d%I64d", &a.x, &a.y, &a.z, &a.dx, &a.dy, &a.dz);
            ll bb = 2 * (a.x*a.dx + a.y*a.dy + a.z*a.dz);
            ll aa = a.dx*a.dx + a.dy*a.dy + a.dz*a.dz;
            ll cc = a.x*a.x + a.y*a.y + a.z*a.z - r*r;
            if (bb*bb - 4 * aa*cc >= 0)
            {
                if (dis(a, point(0, 0, 0))>r*r&&a.x*a.dx + a.y*a.dy +a.z*a.dz >= 0)continue;
                double m1 = max(0.0, (-bb - sqrt((double)bb*bb - 4 * (double)aa*cc)) / 2 / aa);
                double m2 = max(0.0, (-bb + sqrt((double)bb*bb - 4 * (double)aa*cc)) / 2 / aa);
                lr[k].lf = min(m1, m2), lr[k++].ri = max(m1, m2);
            }
        }
        sort(lr, lr + k,cmp);
        c[k - 1] = lr[k-1].ri;
        for (int i = k - 2; i >= 0; i--)c[i] = min(c[i + 1], lr[i].ri);
        printf("Case %d: ", cas++);
        double temp;
        m = 0;
        for (int i = 0; i < k;)
        {
            temp = c[i];
            m++;
            while (i<k&&lr[i].lf <= temp)i++;
        }
        printf("%d %d\n", k, m);
    }
}

 

posted on 2016-04-30 15:26  icode-xiaohu  阅读(197)  评论(0编辑  收藏  举报