牛客编程巅峰赛S1第3场 -黄金&钻石(解题报告)

题目链接:https://ac.nowcoder.com/acm/contest/6383

A-找卧底

题意:原本有n个人,现在多了一个卧底,找出排列中个数超过1的数 

 hint:用vis标记一下已经存在的人,如果已经存在了,那么当前这个人就是卧底

AC代码: 

class Solution {
public:
    /**
     * 
     * @param n int整型 
     * @param a int整型vector 
     * @return int整型
     */
    int search(int n, vector<int>& a) {
        // write code here
        int vis[100005]={0};
        for(int i=0;i<=n;i++){
            if(vis[a[i]])return a[i];
            vis[a[i]]=1;
        }
    }
};

 B-父子情深

题意:n结点的树,以1为根节点,q次操作,将x为根结点的子树上所有的结点权值加k,输出q次操作之后1到n结点的权值 

 

hint:dfs深搜

因为是自上而下的传递,所以可以先将x结点的权值加上k,最后dfs深搜将父结点状态传给子节点 。

 AC代码:

扫描二维码关注公众号,回复: 11485832 查看本文章
/**
 * struct Point {
 *	int x;
 *	int y;
 * };
 */

class Solution {
public:
    int f[123456];
    vector<int>v[123456];
    vector<long>val;
    void add(int a,int b){
        v[a].push_back(b);
        v[b].push_back(a);
    }
    void dfs(int s,int fa){//dfs找爸爸
        for(auto i:v[s]){
            if(i==fa)continue;
            f[i]=s;
            dfs(i,s);
        }
    }
    void dfs1(int s,int fa){//自上而下更新
        for(auto i:v[s]){
            if(i==fa)continue;
            val[i-1]+=val[s-1];
            dfs1(i,s);
        }
    }
    vector<long> solve(int n, vector<Point>& Edge, int q, vector<Point>& Query) {
        // write code here
        val.resize(n,0);
        for(auto i:Edge){
            add(i.x,i.y);
        }
        f[1]=-1;
        dfs(1,-1);
        for(auto i:Query){
            val[i.x-1]+=i.y;
        }
        dfs1(1,-1);
        return val;
    }
};

C-旋转跳跃

题意:给一个初始排列,以及m对(xi,yi)其中xi,yi位置的元素可以交换无数次 ,问最终可以得到的字典序最小的排列

hint:并查集 +sort

可以将同一连通块的下标存放在一个数组里,然后将数组里下标表示的值从小到大排个序,然后再依次放回原排列,那么的得到的排列字典序是最小的

class Solution {
public:
    int pre[123456];
    int find(int a){
        if(a==pre[a])return a;
        return pre[a]=find(pre[a]);
    }
    vector<int>r;
    vector<int>v[123456];
    vector<int> solve(int n, int m, vector<int>& perm, vector<Point>& Pair) {
        // write code here
        for(int i=1;i<=n;i++)pre[i]=i;
        for(auto i:Pair){
            int u=find(i.x),v=find(i.y);
            if(u!=v)pre[u]=v;
        }
        for(int i=1;i<=n;i++){
            int t=find(i);
            v[t].push_back(i);
            if(i==t)r.push_back(i);
        }
        for(auto i:r){
            vector<int>a;
            sort(v[i].begin(),v[i].end());
            for(auto j:v[i])a.push_back(perm[j-1]);
            sort(a.begin(),a.end());
            for(int j=0;j<v[i].size();j++){
                perm[v[i][j]-1]=a[j];
            }
        }
        return perm;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43911947/article/details/107574602