牛客网OJ题解--20210324

Laptop

https://ac.nowcoder.com/acm/problem/14266

本系列记录翀翀😐痛苦的刷题日志,所有题目均来自于牛客网OJ题目,坚持刷题谈起来容易做起来难,希望我可以坚持下去,这里仍然分享一段励志文案:每个人都有梦想,然而有些人把梦想变成了现实,有些人的梦想依旧是梦想,只因为他们为梦想付出的努力程度不一样,他们坚持的时间不一样,最终才有这样的结果。

NC14266-Laptop

题目链接

https://ac.nowcoder.com/acm/problem/14266

题目描述

FST是一名可怜的小朋友,他很强,但是经常fst,所以rating一直低迷。
但是重点在于,他非常适合ACM!并在最近的区域赛中获得了不错的成绩。
拿到奖金后FST决定买一台新笔记本,但是FST发现,在价格能承受的范围内,笔记本的内存和速度是不可兼得的。
可是,有一些笔记本是被另外一些“完虐”的,也就是内存和速度都不高于另外某一个笔记本,现在FST想统计一下有多少笔记本被“完虐”。

第一行一个正整数n,
表示笔记本的数量。接下来n行,每行两个正整数Mi,Si表示这款笔记本的内存和速度。
n≤105,Mi,Si≤109

输出一行,一个正整数,表示被完虐的笔记本数。

测试样例

输入

4
100 700
200 500
50 100
300 400

输出

1

解题思路

实际上是一个简单的排序思维题,首先我们将内存进行从大到小排序,那么第i个pad肯定是不会被第i+1个pad完爆的,因为前者的内存要比后者大,所以检验i完爆的电脑时,只需检验比他内存小的即在他后面的电脑,但是要注意并不是i就一定完爆其他的所有电脑,因为他的速度未必是最大的,所以我们单独枚举i从n到1,即内存从大到小,然后在记录最大的速度值,当被检验的电脑速度也小于i,那么他就被完爆了。

解题代码

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5;
struct Pad
{
    //存储ram和速度
    int a;
    int b;
} pad[N];

bool cmp(Pad x, Pad y)
{
    //将内存从大到小排序
    return x.a > y.a;
}

int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> pad[i].a >> pad[i].b;
    }
    //排序后最靠前的是内存最大的
    sort(pad + 1, pad + 1 + n, cmp);
    int ans = 0;
    //记录最大的速度
    int maxb = 0;
    for (int i = 1; i <= n; i++)
    {
        //更新最大速度
        if (pad[i].b > maxb)
            maxb = pad[i].b;
        else
        {
            //此时pad[i]被完爆了,因为他一定比pad[i-1]之前的ram小
            //此时速度又小了,那么就被完爆了
            ans++;
        }
    }
    cout << ans << endl;
    system("pause");
    return 0;
}

NC14685-加边的无向图

题目链接

https://ac.nowcoder.com/acm/problem/14685

题目描述

给你一个 n 个点,m 条边的无向图,求至少要在这个的基础上加多少条无向边使得任意两个点可达~ 。

第一行两个正整数 n 和 m 。接下来的m行中,每行两个正整数 i 、 j ,表示点i与点j之间有一条无向道路。输出一个整数,表示答案。

测试样例

输入

4 2
1 2
3 4

输出

1

解题思路

就是一个很明显的并查集板子题,连接以后统计连通块数,需要练的边数就是连通块数减一。

解题代码

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 5;

int fa[maxn];
//板子
int find(int x)
{
    return x == fa[x] ? x : (fa[x] = find(fa[x]));
}

void merge(int x, int y)
{
    int i = find(x);
    int j = find(y);
    fa[i] = j;
}

int main()
{
    //初始化,默认每一个孤立点都是一个连通块
    for (int i = 0; i < maxn; i++)
    {
        fa[i] = i;
    }
    int n, m;
    cin >> n >> m;
    //合并
    for (int i = 1; i <= m; i++)
    {
        int x, y;
        cin >> x >> y;
        merge(x, y);
    }
    int ans = 0;
    //统计连通块个数,属于同一个i的是一个连通块
    for (int i = 1; i <= n; i++)
    {
        if (find(i) == i)
            ans++;
    }
    //需要ans-1个边
    cout << ans - 1 << endl;
    system("pause");
    return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务