牛客周赛 Round 154
2026/8/1 21:08:11 网站建设 项目流程

牛客周赛 Round 154补题题解

前言

变色的生活 任性的挑拨
疯狂的冒出了头
单方的守候 试探的挑拨
却还是少了点什么
遥远两端 爱挂在天空飞
风停了也无所谓 只因为你总说
Everything will be okey

本周牛客周赛也是在vp之后的闲余时间开始的,由于vp的难度太高,导致压根不想写牛客的周赛,并且晚上还有cf的周赛,所以就先把它放下了。但是主包还是不太放心,在几天后也是把它给补了。
难度可以说是很低,我们看榜单就可以看出来了
首先A B是两道签到题,能见到两道签到题的周赛也是不多见了,然后C题有点思维转变,D题的话其实也不是很难知识线动成环而已,转动思维思考基本能想出来。

下面我们就随便讲解一下题目吧

题目入口


A题

这题不想说,就是一个纯签到题,就跟hello world一样,代码如下

double a; cin>>a; cout<<(int)a<<endl;

B题

这个题也很简单,读完题我们就知道怎么写了,它想要两个一样的数组重新排序使得差值绝对值和最大,那肯定是一个正序一个倒序啊,秒了

int n; cin>>n; for(int i=1;i<=n;i++) cout<<i<<' '; cout<<endl; for(int i=n;i>=1;--i) cout<<i<<' '; cout<<endl;

C题

这个题的话就是让我们找一个构造方法使得小红位置绝对值和最大,那我们在宏观角度就能想,y轴的值只跟上下有关,x轴得值只跟左右有关,所以y周我们只看上下,x我们只看左右。

首先是有k次删除操作的,我们可以这样删看看哪两个最多啊(这里的两个是上下其中一个,左右其中一个),然后我们就删除剩余两个,一直删除,如果遍历完串k还没用完那就随便删除这两个多的方向上的,直到k等于0就结束,我们把修改后的输出出来就行了。

实现方式可以是定义一个对应下标的数组,下标是0就是存在,1就是不存在

// Problem: 小红的序列删除 // Contest: NowCoder // URL: https://ac.nowcoder.com/acm/contest/137840/C // Memory Limit: 512 MB // Time Limit: 2000 ms // author:世间 // Date:2026-07-30 18:46:19 #include<bits/stdc++.h> using namespace std; #define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) #define endl '\n' #define int long long #define pii pair<int,int> #define fi first #define se second #define YES cout<<"YES"<<endl; #define NO cout<<"NO"<<endl; const int INF=1e6+5; void solve() { int n,k; cin>>n>>k; vector<int> vis(n+3,0); int left=0,right=0,up=0,down=0; string s; cin>>s; for(int i=0;i<n;i++) { if(s[i]=='U') up++; if(s[i]=='D') down++; if(s[i]=='L') left++; if(s[i]=='R') right++; } char ch1='D',ch2='R'; if(up<=down) ch1='U'; if(left<=right) ch2='L'; for(int i=0;i<n;i++) { if((s[i]==ch1||s[i]==ch2)&&k>0){ k--; vis[i]=1; } if(k==0) break; } if(k>0){ for(int i=0;i<n;i++) { if(vis[i]==0){ vis[i]=1; k--; } if(k==0) break; } } for(int i=0;i<n;i++) { if(!vis[i]) cout<<s[i]; } cout<<endl; // cout<<fixed<<setprecision(x)<< } signed main() { IOS; int _=1; // cin>>_; while(_--) solve(); return 0; }

D题

这个题考察的就是一个环的转换,而环的情况下我们可以用到期末来做到环的性质,首先我们想到如果一次操作我们遍历一次那肯定是超时的,所以这种想法很定时行不通的,所以我们肯定得做预处理。我们可以先对它找相邻不同的个数。然后我们可以用01来表示相邻两个之间的状态,然后开始进行q次操作,它每次给你的lr都有这样的性质,中间的状态不会改变而两边会改变(当然了我说的是常规情况),我们肯定得特判其他情况了,比如说n==1,我们就不需要判断直接输出0,然后要是lr长度为n那也不需要判断,全部反转等于没有反转,直接输出ans,然后就是r>l的情况,这种情况我们可以这样转化r变成l,l变成r,然后再判断l处的情况,r处的情况进行0变1 1变0,ans++或者ans–。根据这些我们就可以写出来了

// Problem: 小红的01串 // Contest: NowCoder // URL: https://ac.nowcoder.com/acm/contest/137840/D // Memory Limit: 512 MB // Time Limit: 2000 ms // author:世间 // Date:2026-07-30 19:20:29 #include<bits/stdc++.h> using namespace std; #define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) #define endl '\n' #define int long long #define pii pair<int,int> #define fi first #define se second #define YES cout<<"YES"<<endl; #define NO cout<<"NO"<<endl; void solve() { int n,q; cin>>n>>q; string s; cin>>s; int ans=0; vector<int> v(n); for(int i=0;i<n;i++) { v[i]=(s[i]==s[(i+1)%n]); if(!v[i]) ans++; } while(q--) { int l,r; cin>>l>>r; int len=(l<=r)?(r-l+1):(n-l+r+1); if(n==1){ cout<<0<<endl; continue; } if(len==n){ cout<<ans<<endl; continue; } if(l>r){ int L=(r+1)%n; int R=(l-1+n)%n; l=L; r=R; } int shu1=(l-1+n)%n; if(v[shu1]) ans++; else ans--; v[shu1]^=1; int shu2=r; if(shu1!=shu2){ if(v[shu2]) ans++; else ans--; v[shu2]^=1; } cout<<ans<<endl; } // cout<<fixed<<setprecision(x)<< } signed main() { IOS; int _=1; // cin>>_; while(_--) solve(); return 0; }

后面两题有机会再补吧。其实算法涉及不太多,重在思维,这周的牛客就是重在思维,感觉质量也不是太高啊,所以想补题的建议看看后面两题了。

这期有点水了,奈何主包实力有限,有机会一定大展一篇啊。

希望对你有帮助!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询