hdu5714 思维+区间内线段最

原创 2016年06月01日 10:43:41

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5714


题目大意:给你n只小船,给你每个船的左端点和右端点,以及航行方向(左,右)和到岸边的距离,每个船的航行距离一样。如果有个人在岸边且只能垂直于岸边拍摄(与岸边呈45度角),问最多可以拍到多少只完整的小船。

思路:

1、首先,因为所有船只航速一样,所以同一方向的船只相对静止。

2、如果在l点可以拍摄到向右航行的船只数目为num1,在r点可以拍摄到向左航行的船只数量为num2,l<=r,那么一定存在某一时刻拍摄到的船只数量等于num1+num2.这个很好证明,两个同样的三角形相向而行,必定会重合。


3、如果有y-x>2z,则该船不可能出现在镜头中。如果y-x<=2z,那么该船可被拍摄的范围是(y-z,x+z),画个图就理解了。但是做的时候把范围搞成了(x+z , y-z)。。。显然错了


4、我们可以处理出所有船只可被拍摄的范围,然后求区间内线段个数最多的点。方法是左端点标记为1,右端点标记为-1,排序后从左到右扫描一遍,遇到1++,遇到-1--;

5、不同方向的船只分开处理。

复杂度nlogn。


#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <iomanip>

using namespace std;
//#pragma comment(linker, "/STACK:102400000,102400000")
#define maxn 1000005
#define MOD 1000000007
#define mem(a , b) memset(a , b , sizeof(a))
#define LL long long
#define ULL unsigned long long
const long long INF=0x3fffffff;

int n , t;
struct node
{
    int val , flag ,d;

} a[maxn] , b[maxn];

int ans[maxn];

bool cmp(node n1,node n2)
{
    if(n1.val != n2.val) return n1.val < n2.val;
    else if(n1.flag != n2.flag) return n1.flag > n2.flag;
    else return n1.d < n2.d;
}

int main()
{
    scanf("%d" , &t);
    int cas = 0;
    while(t--)
    {
        mem(ans , 0);
        scanf("%d" , &n);
        int x , y ,  z , d;
        int id1 = 0 , id2 = 0;
        for(int i = 0 ; i < n ; i ++)
        {
            scanf("%d %d %d %d" , &x , &y , &z , &d);
            x += 1000000;
            y += 1000000;
            if((y - x) > 2*z) continue;
            a[id1].val = x + z;
            a[id1].d = d;
            a[id1++].flag = -1;
            a[id1].val = y - z;
            a[id1].d = d;
            a[id1++].flag = 1;
        }
        sort(a , a + id1 , cmp);
        int ans1 = 0 ;
        int num = 0;
        for(int i = id1 - 1; i >= 0 ; i --)
        {
            if (a[i].d < 0 && a[i].flag == -1) num++;
            ans[i] = max(ans[i + 1], num);
            if (a[i].d < 0 && a[i].flag == 1) num--;
        }
        num = 0;
        for(int i = 0 ; i < id1 ; i ++)
        {
            if(a[i].d > 0)
            {
                if(a[i].flag == 1) num++;
                ans1 = max(ans1 , num + ans[i]);
                if(a[i].flag == -1) num--;
            }
        }
        printf("Case #%d:\n%d\n", ++cas, ans1);

    }
    return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

HDU-5714-拍照(区间线段覆盖)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5714 拍照 Time Limit: 6000/3000 MS (Java/Others) ...

Hdu 4283 You Are the One【区间Dp+思维】好题!

You Are the One Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)...

HDU1556 - Color the ball - 思维+线段树/树状数组/前缀和

1.题目描述: Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (...

HDU 5714 拍照 [杂题] [离散化]

拍照 Time Limit: 3000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64uDescription 小...

【线段树-思维】hdu 6047

Maximum Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others...

hdu 2492 Ping pong(线段树+思维)

Ping pong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota...

hdu 4893 (多校1007)Wow! Such Sequence!(线段树&二分&思维)

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth...

hdu 2795 Billboard(有点思维的线段树水题)

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot...

线段树专题#5_蒟蒻训练历程记录_HDU 1394 Minimum Inversion Number_单点更新+思维转换

啊这道题思维比较巧妙,首先用线段树单点更新从后往前求得每一位的逆序数个数,相加得出逆序数的总和。然后就是要思考的东西了:从一个序列转换为另一个序列时,把数组的第一个元素移到数组尾部,那么这个时候逆序数...

HDU 5714 树状数组 + 离散化

题意: Problem Description 小明在旅游的路上看到了一条美丽的河,河上有许多船只,有的船只向左航行,有的船只向右航行。小明希望拍下这一美丽的风景,并且把尽可能多的船只...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)