• 牛客网算法竞赛难题


    闲的没事参加了一下牛客网的算法训练赛

    才发现这么难(划掉

    才发现我对时间和空间复杂度的运算能力这么差

    其中有一道题我的代码超过了空间限制

     而另外一个人的没有。。。

     还AC了

    但是对比我们两个的代码我发现

    好像开的数组一样大,我甚至还把一个数组换成了vector,但是还是内存爆掉了

    搞不清为什么

    原题如下:

    糖果

    题目描述:

    在一个幼儿园里面有nmathit nn个小朋友,分别编号1,2,...,n ext 1,2,...,n1,2,...,n。在这些小朋友中有一些小朋友互为朋友关系,总共有mmathit mm对朋友。
    作为幼儿园老师,你想买一些糖果分给小朋友,你知道第imathit ii个小朋友想要至少aia_{i}ai个糖果,否则他就会不开心。
    同时,如果一个小朋友得到的糖果数小于他某个朋友得到的糖果数,他也会不开心。
    请问你最少买多少糖果才能保证每个小朋友都不会不开心呢?

    链接:https://ac.nowcoder.com/acm/contest/9983/G
    来源:牛客网

    输入描述:

    第一行以空格分隔的两个整数n,m
    第二行以空格分隔的n个正整数ai
    接下来m行每行以空格分隔的两个正整数u,v,代表uv的朋友,vu的朋友。

    输出描述:

    购买的最少糖果数以保证每个小朋友都不会不开心。

    输入

    3 1
    1 2 3
    1 2

    输出

     7

    说明

    给第三个小朋友买3个糖果,前两个小朋友都买2两个糖果,总共至少买7个糖果。注意如果给第一个小朋友只买了1个糖果,那么他在看到自己的好朋友2有2个糖果的情况下,他就会不开心。

    这道题题面上没有说朋友的朋友就是自己朋友

    但也不难分析出来

    假如A是B的朋友,c是B的朋友

    A想要2颗糖,B想要3颗,C想要五颗

    为了让C开心,C会得到5颗糖

    为了让B开心,B也会得到五颗,因为B是C的朋友,当ta瞅瞅C手中的五颗糖和自己手中的三颗糖时,会很不开心

    同理,为了让A开心,也给A五颗糖

    A得到的糖数量与C相等

    所以说这道题有考到并查集

    那么我的代码是这样的:

     1 #include <bits/stdc++.h>
     2 #include <vector>
     3 using namespace std;
     4 int n,m,a,b,sum[1000005],head[1000005],ww;
     5 vector <int> w;
     6 long long ans;//经过计算,我认为ans的值可能会超过int类型
     7 int find(int x){//寻找两拨孩子的头目
     8     if(head[x]!=x)
     9     head[x]=find(x);
    10     return head[x];
    11 }
    12 void hb(int x,int y){//把两拨孩子合并
    13     int xx=find(x);
    14     int yy=find(y);
    15     head[yy]=xx;
    16 }
    17 int main(){
    18     w.push_back(0);
    19     cin>>n>>m;
    20     for(int i=1;i<=n;i++){
    21         head[i]=i;//初始化头领
    22         sum[i]=1;//初始化队伍人数
    23     }
    24     for(int i=1;i<=n;i++){
    25         cin>>ww;
    26         w.push_back(ww);
    27     }
    28     for(int i=1;i<=m;i++){
    29         cin>>a>>b;
    30         if(find(a)!=find(b)){
    31             sum[find(a)]+=sum[find(b)];//把两拨人数相加
    32             hb(a,b);
    33             w[find(a)]=max(w[a],w[b]);//寻找这些人中,想要糖果最多的数量
    34         }
    35     }
    36     for(int i=1;i<=n;i++){
    37         if(head[i]==i){//找到每队头领,代表该队即可;
    38             ans+=sum[i]*w[i];
    39         }
    40     }
    41     cout<<ans;
    42     return 0;
    43 }

    别人家的代码长这样(注释是根据我自己的理解写的,他才没那么善良

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <vector>
     4 using namespace std;
     5 int fa[1000005];//头目
     6 inline int ff(int x)//相当于我代码里的find函数
     7 {
     8     if(fa[x]==x) return x;
     9     return fa[x]=ff(fa[x]);
    10 }
    11 int mx[1000005],sz[1000005],a[1000005];
    12 int main(int argc, char** argv){ //main函数里加代码我还是第一次见,详情见博客https://blog.csdn.net/hopeneversleep/article/details/55798722
    13     int n,m;
    14     cin >> n >> m;
    15     for(int i=1;i<=n;i++) fa[i]=i;//初始化头目
    16     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    17     
    18     for(int i=1;i<=m;i++)
    19     {
    20         int u,v;
    21         scanf("%d%d",&u,&v);
    22         fa[ff(u)]=ff(v); //合并小组   
    23     }
    24     for(int i=1;i<=n;i++)
    25     { 
    26         mx[ff(i)]=max(mx[ff(i)],a[i]);
    27         sz[ff(i)]++;
    28     }//把小组里糖果最大需求量和小组人数单独统计
    29     long long ans=0;//同样是long long
    30     for(int i=1;i<=n;i++) ans+=(long long)sz[i]*mx[i];
    31     cout << ans;
    32     return 0;
    33 }
  • 相关阅读:
    div定位左右居中
    highcharts绘制3D倾斜的饼图
    Echarts 图表不能渲染问题整理
    RK:系统手势监听
    RK:网络共存、Shell脚本
    泛型
    ArrayList类
    Linux(centos7)安装ClickHouse
    centos安装宝塔命令
    centos下修改hosts文件以及生效命令
  • 原文地址:https://www.cnblogs.com/TFLSc1908lzs/p/14382564.html
Copyright © 2020-2023  润新知