nyoj 1275 导弹发射(河南省2016年省赛)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27437781/article/details/71172917

导弹发射

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描述

Alpha 机构研发出一种新型智能导弹,它能够在雷达检测到的区域内,选择一条前进的路径,击破路径上所有的目标物。雷达位于(0,0)处,它能够检测到两条射线之间的区域(不妨设在第一象限)。导弹一开始置放在(0,0)处,它可以在雷达能检测到的区域内先选择一个目标物击破,然后再继续前进,选择另一个目标物击破。注意,导弹不能沿着这两条射线前进,当然也不能停在原地。可以假设,导弹一旦发射,其能量无比大,前进的路径无限长。已知雷达能够检测到区域,其射线 1:ax-by=0 和射线 2:cx-dy=0。Alpha 机构的总指挥希望在发现目标群的第一时刻,计算出一条可以击破最多目标物的路径。 

输入
第一行: T 表示以下有 T 组测试数据(1≤T ≤8)
对每组测试数据:
第 1 行: n 表示目标物的个数
第 2 行: a b c d 代表两条射线的斜率分别是 a/b 和 c/d。
接下来有 n 行,每行 2 个正整数 xi yi 即第 i 个目标物的坐标。
【约束条件】
(1) n<=10^5 0<=a, b, c, d<=10^5 a 和 b 不会同时为 0,c 和 d 不会同时为 0;
(2) 0<= xi , yi <=10^6 i=1,…..,n
输出
每组测试数据,输出占一行,即导弹能击破的最多目标数。
样例输入
1
15
1 3 2 1
3 1
6 2
4 2
2 5
4 5
6 6
3 4
1 6
2 1
7 4
9 3
5 3
1 3
15 5
12 4
样例输出
4
来源

河南省第九届省赛


LIS的思想,不能用n2的算法,会超时,要用nlogn的算法。

首先我们建坐标,我们以射线1和射线2分别为x轴和y轴,建立坐标系,这样我们就把问题转换成简单的LIS了。


AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Node
{
    double x;
    double y;
}node[100005];
Node ans[100005];
int len;
bool cmp(Node a, Node b)
{
    if(a.x==b.x)
        return a.y < b.y;
    else
        return a.x < b.x;
}
int binary_search(int i)
{
    int left = 0, right = len;
    int mid;
    while(left <= right)
    {
        mid = (left + right)/2;
        if(ans[mid].y < node[i].y) left = mid + 1;
        else right = mid - 1;
    }
    return left;
}
int main()
{
    int T, k;
    scanf("%d",&T);
    while(T--)
    {
        k = 0;
        int n;
        scanf("%d",&n);
        int a, b, c, d;
        double k1, k2, k3, t;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        k1 = a*1.0/b;
        k2 = c*1.0/d;
        if(k1 > k2)
        {
            t = k1;
            k1 = k2;
            k2 = t;
        }
        int x, y;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d%d",&x,&y);
            k3 = 1.0*y/x;
            if(k3 > k1&&k3 < k2)
            {
                node[k].x = x*1.0 - y*1.0/k2;
                node[k].y = y*1.0 - k1*x;
                k++;
            }
        }
        sort(node , node + k, cmp);
        memset(ans, 0, sizeof(ans));
        len = 1;///刚开始的时候长度为1  目前最小的就是第一个数
        ans[0] = node[0];
        ///这里用最长上升子序列nlogn的时间复杂度来进行计算
        for(int i = 1; i < n; i++)
        {
            if(node[i].y > ans[len-1].y&&node[i].x > ans[len-1].x) ///如果下一个的x和y都比现在的大  那么就把这个坐标加上去 len++
            {
                ans[len++] = node[i];
            }
            else
            {
                int pos = binary_search(i);
                ans[pos] = node[i];
            }
        }
        printf("%d\n",len);
    }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/qq_27437781/article/details/71172917