牛客周赛77文字版题解

A.时间表

把所有时间存在字符串数组中,输出对应的下标。

时间复杂度:

void solve(){
    vector<string>a{
        "20250121",
        "20250123",
        "20250126",
        "20250206",
        "20250208",
        "20250211"
    };
    int x;cin>>x;
    cout<<a[x-1];
}

B.数独数组

对于此类数独,一定存在连续的周期使得每个数字的出现次数相同,然后最后存在一段连续的数字都恰好出现一次。 故只要判断数字的最少次数和最多次数差距不大于 即可。

时间复杂度:

void solve(){
    int n;
    cin>>n;
    vector<int>a(n+1);
    vector<int>cnt(10);
    for(int i=1;i<=n;i++){
        cin>>a[i];
        cnt[a[i]]++;
    }
    for(int i=1;i<=9;i++){
        for(int j=i+1;j<=9;j++){
            if(abs(cnt[i]-cnt[j])>1){
                cout<<"NO\n";
                return ;
            }
        }
    }
    cout<<"YES\n";
}

C. 小红走网格

对于行列移动本质上是分离的。

考虑行移动,每次能向上移动 个单位或向下移动 ,那么对于 的倍数都可以达到,所以只需要判断 是否是 的倍数即可。

对于列移动同理。

时间复杂度:,其中 是移动的距离。

void solve(){
    i64 a,b,c,d,x,y;
    cin>>x>>y>>a>>b>>c>>d;
    i64 g1=gcd(c,d);
    i64 g2=gcd(a,b);
    if(x%g1==0&&y%g2==0){
        cout<<"YES\n";
    }else{
        cout<<"NO\n";
    }
}

D.隐匿社交网络

假设两个数字在二进制位上存在某位都是 ,那么其必然满足

我们可以按位分成 个类,若一个数在对应位上是 ,则把它放进对应的容器里。

那么就可以考虑按位并查集,先把可以合并的位合并,然后合并对应容器里的数字,再归纳去重即可。

最后比较容器里的数字个数,最多的便是答案。

时间复杂度:

void solve(){
    int n;
    cin>>n;
    vector<i64>a(n+1);
    vector<int>p(64);
    iota(p.begin(),p.end(),0);
    auto find=[&](auto &&self,int x)->int {
        if(p[x]==x) return x;
        p[x]=self(self,p[x]);

        return p[x];
    };
    vector<vector<int>>vv(64);
    for(int i=1;i<=n;i++){
        cin>>a[i];
        vector<int>v;
        for(int j=0;j<=63;j++){
            if(a[i]>>j&1){
                v.push_back(j);
            }
        }  
        vv[v[0]].push_back(i);
        for(int j=1;j<v.size();j++){
            vv[v[j]].push_back(i);
            int f1=find(find,p[v[j]]);
            int f2=find(find,p[v[j-1]]);
            if(f1!=f2){
                p[f1]=p[f2];
                
            }
        }
    }
    vector<vector<int>>ans(64);
    for(int i=0;i<=63;i++){
        int fa=find(find,i);
        for(auto t:vv[i]){
            ans[fa].push_back(t);
        }
    }
    int res=0;
    for(int i=0;i<=63;i++){
        sort(ans[i].begin(),ans[i].end());
        ans[i].erase(unique(ans[i].begin(),ans[i].end()),ans[i].end());
        res=max(res,(int)ans[i].size());
    }
    cout<<res<<"\n";
}

E.1or0

题意转化为求询问区间有多少个子区间包含

那么我们可以转化为询问区间的子区间个数减去区间中不包含 的区间个数。

先使用前缀和统计到 时全是 的子区间个数。

再用序列自动机预处理对于任意 其前缀和后缀中最远的 的位置,使得 到该位置的字符全是

对于 ,如果 , 那么说明答案便可以直接用 ,因为该区间是不会存在 和前面的位置产生新的全 区间。 alt

如果 ,说明我们多减去了如果红色乘以蓝色的区间个数,再加上即可,当然蓝色区间可能超过 ,所以还要对 取一下较小值。

时间复杂度:

void solve(){
    int n;
    string s;
    cin>>n>>s;
    s=" "+s;
    vector<i64>ans(n+2);
    int idx=-1;
    vector<int>pre(n+5,-1);
    vector<int>suf(n+5,-1);
    for(int i=1;i<=n;i++){
        ans[i]=ans[i-1];
        pre[i]=pre[i-1];
        if(s[i]=='0'){
            if(idx==-1){
                ans[i]+=1;
            }else{
                ans[i]+=(i-idx+1);
            }
            if(idx==-1) idx=i;
        }else{
            idx=-1;
        }
        if(s[i]=='0'&&(s[i-1]=='1'||i-1==0)){
            pre[i]=i;
        }
    }
    suf[n]=(s[n]=='0'?n:-1);
    for(int i=n-1;i>=1;i--){
        suf[i]=suf[i+1];
        if(s[i]=='0'&&s[i+1]=='1'){
            suf[i]=i;
        }
    }
    int q;
    cin>>q;
    while(q--){
        int l=-1,r=-1;
        cin>>l>>r;
        i64 len=r-l+1;
        i64 sum=(1+len)*len/2;
        sum-=ans[r]-ans[l-1];
        if(s[l]=='0'){
            int right=min(suf[l],r);
            int left=pre[l];
            sum+=1LL*(right-l+1)*(l-left);
        }
        cout<<sum<<"\n";
    }
}

F.计树

首先我们先记录哪些结点为给定的目标结点,接着对每个结点 考虑它作为目标结点 的次数。

同时记录对于第 个结点的子树下的目标结点数量为

对于任意一个 的子结点 ,我们考虑对于已经遍历的 的兄弟结点的子树下的目标结点数量为 ,那么此时 作为 新增的次数就是

特别地,若该结点是目标结点,可作为自身的

时间复杂度:

void solve(){
    int n;
    cin>>n;
    vector<vector<int>>e(n+1);
    for(int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    int k;
    cin>>k;
    vector<bool>ok(n+1,false);
    for(int i=1;i<=k;i++){
        int s;
        cin>>s;
        ok[s]=true;
    }
    vector<i64>ans(n+1);
    vector<i64>num(n+1);
    auto dfs=[&](auto &&self,int u,int fa)->void {
        i64 temp=0;
        if(ok[u]) temp++;
        for(auto v:e[u]){
            if(v==fa) continue;
            self(self,v,u);
            ans[u]+=num[v]*temp*2;
            temp+=num[v];
            num[u]+=num[v];
        }
        if(ok[u]) num[u]++;
        if(ok[u]) ans[u]++;
        
    };
    dfs(dfs,1,-1);
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<" ";
    }
}
全部评论
交作业:
4 回复 分享
发布于 2025-01-20 16:16 江苏
那个E题涉及啥知识点呀,萌新看不懂
1 回复 分享
发布于 2025-01-20 08:51 江西
有python题解吗
点赞 回复 分享
发布于 2025-01-20 18:58 河南

相关推荐

1.&nbsp;自我介绍2.&nbsp;项目都是自己写的吗?3.&nbsp;我看你用&nbsp;koa2&nbsp;写后端,为什么选择它,能讲讲吗?4.&nbsp;那你提到&nbsp;koa2&nbsp;它是不提供中间件的,你是怎么解决的?5.&nbsp;中间件的原理是什么?(洋葱模型)6.&nbsp;你刚刚说碰到&nbsp;next()&nbsp;就进入下一个中间件,那&nbsp;next&nbsp;只能执行同步,如果是异步的话,你是怎么处理的?(async/await,但是我发现,有的中间件需要在异步中间件之前执行,所以我用&nbsp;try/catch&nbsp;来处理异步中间件的异常)7.&nbsp;JS&nbsp;异步发展史,以及它们的优缺点说一下&nbsp;(回调函数--Promise--Generator--async/await)8.&nbsp;你刚刚说&nbsp;Promise&nbsp;状态不能更改,那如果我要设计一个能修改&nbsp;Promise&nbsp;状态的函数,你会怎么设计?9.&nbsp;CSS&nbsp;水平垂直居中的方法(flex、grid、绝对定位&nbsp;+&nbsp;margin:auto、绝对定位&nbsp;+&nbsp;负&nbsp;margin、绝对定位&nbsp;+&nbsp;transform、table-cell)10.&nbsp;你刚刚说到&nbsp;flex&nbsp;布局,那&nbsp;flex:1&nbsp;是什么意思?(flex:&nbsp;flex-grow&nbsp;&nbsp;flex-shrink&nbsp;&nbsp;flex-basis;等价&nbsp;flex:1&nbsp;1&nbsp;0%表示元素可以均分剩余空间,可拉伸、可压缩,不依赖内容宽度,自动自适应填充布局。)11.&nbsp;父容器宽是&nbsp;500px,然后它左右各有两个子容器是&nbsp;100px,如果设置&nbsp;flex:&nbsp;1,那它的宽度是多少?(500-100-100=300px)12.&nbsp;说说你对浏览器缓存的理解(强缓存、协商缓存)13.&nbsp;如果一个用户,他怎么去刷新都无法刷到最新版的代码,你能说下可能的原因吗?(版本号、hash等)还有吗?(我说我不知道了,面试官说还有&nbsp;CDN&nbsp;没有同步,我说企业才会这么干,自己写项目一般不会,我知道&nbsp;cdn&nbsp;是用来解决高并发的手段)14.&nbsp;React你熟吗?说下&nbsp;React&nbsp;函数组件和类组件的区别15.&nbsp;怎么避免&nbsp;Hooks&nbsp;导致组件重新渲染?(使用&nbsp;useCallback、useMemo、React.memo、useRef等等)16.&nbsp;谈一下我对&nbsp;React&nbsp;的状态管理的理解(Redux、Mobx、Zustand,我说&nbsp;Zustand&nbsp;用的最多)17.&nbsp;React&nbsp;常见的&nbsp;hooks&nbsp;有哪些?(useState、useEffect、useRef、useCallback、useMemo、useReducer、useContext、useImperativeHandle、useLayoutEffect、useDebugValue)18.&nbsp;TS&nbsp;你熟吗?我们引进&nbsp;TS&nbsp;的目的是为什么?19.&nbsp;interface&nbsp;和&nbsp;type&nbsp;的区别20.&nbsp;说下&nbsp;TS&nbsp;里的泛型21.&nbsp;我现在有十个字段,比如十个字段就要&nbsp;A&nbsp;B&nbsp;C&nbsp;D&nbsp;E&nbsp;F&nbsp;G&nbsp;这种。那我现在另有另外一个方法,这个方法接受的参数呢,必须是这个&nbsp;interface&nbsp;A&nbsp;里面的这个&nbsp;K。就比如说你可以是&nbsp;A&nbsp;B&nbsp;C&nbsp;可以&nbsp;A&nbsp;B&nbsp;C&nbsp;D&nbsp;任何组合都可以,但是必须是这个&nbsp;interface&nbsp;里面的&nbsp;A&nbsp;里面的定义的。这个&nbsp;K&nbsp;这种类型的话是怎么去定义呢?(说实话我有点不太理解啥意思,反正我说了&nbsp;keyof)```&nbsp;TypeScriptinterface&nbsp;Obj&nbsp;{A:&nbsp;stringB:&nbsp;stringC:&nbsp;stringD:&nbsp;stringE:&nbsp;string//&nbsp;其他字段...}```22.&nbsp;vite&nbsp;用过吗?说说和&nbsp;webpack&nbsp;的区别。vite&nbsp;的优缺点是什么23.&nbsp;说说&nbsp;Tree&nbsp;shaking(树摇)&nbsp;和&nbsp;Code&nbsp;Splitting&nbsp;(代码分割)的区别24.&nbsp;Git&nbsp;你熟吗?说说&nbsp;git&nbsp;merge&nbsp;和&nbsp;git&nbsp;rebase&nbsp;的区别,什么时候用&nbsp;git&nbsp;merge,什么时候用&nbsp;git&nbsp;rebase?25.&nbsp;web3&nbsp;你熟吗?(不太熟,听说过而已)26.&nbsp;我看你自我介绍说了&nbsp;AI,你是怎么用的?27.&nbsp;除了提示词,还有什么能让&nbsp;AI&nbsp;更聪明?28.&nbsp;AI&nbsp;的优缺点你说一下29.&nbsp;AI&nbsp;发展这么快,你觉得我们以后会扮演什么角色?30.&nbsp;反问基本都答上来了。面了我80分钟,我还以为稳过的
查看29道真题和解析
点赞 评论 收藏
分享
评论
8
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务