PayPal2019春招实习生笔试题的题目

题目简单描述:给你n个点的坐标(x, y),均为浮点数。

如果任意两个点之间的欧几里得距离小于给定的一个浮点值,则认为这两个点之间有关联,并且关联具有传递性,总之就是尽可能扩大一个集合。

输入:

d 欧式距离

n 用户数

接下来每个用户的坐标。

2.0
5
3.0 5.0
6.0 13.0
2.0 6.0
7.0 12.0
0.0 2.0

输出:

[[0, 2], [1, 3], [4]]

 

实现:并查集的应用

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <set>
#include <algorithm>
#include <vector>

using namespace std;

struct node
{
    double x, y;
}cur;

int fa[10000];

double disE(node A, node B)
{
    return ( fabs(A.x - B.x)*fabs(A.x - B.x) + fabs(A.y-B.y)*fabs(A.y-B.y) );
}

int findset(int x)
{
    return fa[x]!=x ? fa[x] = findset(fa[x]) : x;
}

int main()
{
    double dis;
    int n;
    scanf("%lf", &dis);
    scanf("%d", &n);

    vector<node>q;
    double a, b;

    for(int i=0; i<n; i++) {
        scanf("%lf %lf", &a, &b);
        cur.x = a;
        cur.y = b;
        q.push_back(cur);
    }
    for(int i=0; i<n; i++) {
        fa[i] = i;
    }

    dis = dis * dis;
    for(int i=0; i<q.size(); i++) {
        for(int j=0; j<q.size(); j++) {
            if(disE(q[i], q[j]) <= dis) {
                // fa[findset(j)] = findset(i);
                int xx = findset(i);
                int yy = findset(j);
                if(xx == yy)
                    continue;
                else if(xx < yy)
                    fa[yy] = xx;
                else if(xx > yy)
                    fa[xx] = yy;
            }
        }
    }

    for(int i=0; i<n; i++) {
        if(fa[i] != i)
            fa[i] = findset(fa[i]);
    }

    printf("[");
    bool first=true;

    for(int i=0; i<n; i++) {
        if(fa[i] == i) {
            if(first == false)
                printf(", ");
            first = false;
            printf("[");
            printf("%d", i);
            for(int j=i+1; j<n; j++) {
                if(fa[j] == i)
                    printf(", %d", j);
            }
            printf("]");
        }
    }
    printf("]\n");
    return 0;
}

 

[编程题] 弹幕

时间限制:2秒

空间限制:49152K

弹幕是现今网络视频常见的评论方式,能够反映一个视频的火爆程度。假设某个时间一共有N条弹幕,每条弹幕i的持续时间为两个整数表示的时间区间(a[i],b[i]),我们定义弹幕数量最多的一个时间段为最精彩时段,求一个视频的最精彩时段。


输入描述:
第一行整数N,代表弹幕的条数,其中90%的 N < 1000000, 60%的N < 10000
第二行到第N+1行,是两个整数(a[i],b[i]),代表每条弹幕的开始时间和结束时间, 请注意(a[i],b[i])是全开区间, 并且a[i], b[i] < 100

输出描述:
M行,每行两个整数(c,d),M是答案个数,(c,d)代表视频最精彩时段的开始时间和结束时间,并且M个答案区间互不重叠。答案请按照开始时间从小到大输出。请注意每行结尾应包含换行符,包括最后一行。

 输入输出的样例参见牛客网的题目

通过的代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <set>
#include <algorithm>
#include <vector>

using namespace std;
int f[1000001];
set<int>bound;
int main()
{
    int n;
    scanf("%d", &n);
    memset(f, 0, sizeof(f));
    while(n--) {
        int a, b;
        scanf("%d %d", &a, &b);
        bound.insert(a);
        bound.insert(b);
        for(int i=a+1; i<=b; i++)
            f[i]++;
    }
    int big = 0;
    for(int i=0; i<100; i++) {
        if(f[i] > big)
            big = f[i];
    }
    int left, right;
    for(int i=1; i<100; i++) {
        if(f[i] == big) {
            left = i-1;
            int j=i;
            while(f[j] == big && bound.find(j) == bound.end()) {
                j++;
            }
            right = j;
            // printf("***\n");
            printf("%d %d\n", left, right);
            i=j;
        }
    }
    return 0;
}

  

posted @ 2019-03-30 14:27  我喜欢旅行  阅读(608)  评论(0编辑  收藏  举报