The third week
追光的人永远光芒万丈
一.前言
寒假集训第三周,这周主要是在打个人赛和牛客,打了三场牛客,总体来说还可以,第三场只过了5个题,两个题实在没调出来。这周也在写一些dp的题。

这周补了:乘法逆元,质因数分解, 完全二叉树,位运算,并查集,二分答案, 数位DP。
二.部分题解与思路
1.C-Inverted World_2026牛客寒假算法基础集训营3
题目复现

解题思路
要将 01 串转为相邻不同的交替串,需以0101...和1010...两种目标分别计算最小操作数再取最小值;对单个目标,先提取原串中位置和字符匹配目标的字符组成新串,将新串的 1 记 + 1、0 记 - 1,求该序列的最大子段和与最小子段和,二者绝对值的最大值即为该目标下的最少操作数,一次操作可反转交替子序列,能缩小一段的字符匹配优势差 1,故最小操作数等于全局最大优势差。
code
cpp
#include<bits/stdc++.h>
using namespace std;
using ll= unsigned long long ;
const int N=2e6+5;
#define endl '\n'
int f(string s){
int mx=0,mn=0,now=0;
for(int i=0;i<(int)s.size();i++){
if(s[i]=='1')now++;
else now--;
if(now<0)now=0;
mx=max(mx,now);
}
now=0;
for(int i=0;i<(int)s.size();i++){
if(s[i]=='1')now++;
else now--;
if(now>0)now=0;
mn=min(mn,now);
}
return max(mx,abs(mn));
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int _;
cin>>_;
while(_--){
ll n;
string s,t;
cin>>n>>s;
t="";
for(int i=0;i<n;i++){
if((i&1)&&s[i]=='1')t+=s[i];
if(!(i&1)&&s[i]=='0')t+=s[i];
}
int ans=f(t);
t="";
for(int i=0;i<n;i++){
if((i&1)&&s[i]=='0')t+=s[i];
if(!(i&1)&&s[i]=='1')t+=s[i];
}
ans=min(ans,f(t));
cout<<ans<<endl;
}
return 0;
}
2.J-Branch of Faith_2026牛客寒假算法基础集训营3
题目复现

解题思路
就是数据结构的一些公式,直接看注释就可以了,注意用1<<n的方式来不要用pow函数

code
cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N=2e6+5;
# define endl '\n'
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--) {
ll n, q;
cin >> n >> q;
int sum = __lg(n); //树深度
while (q--) {
ll x;
cin >> x;
int d = __lg(x);//节点x深度
if (d < sum) {//不是最后一层就是满的
cout << (1LL << d) << endl;//2的d次方
} else if (d == sum) {//最后一层
ll sum0= (1LL << sum) - 1;//算前面层总节点
cout << n - sum0 << endl;//总的-前面的就是最后一层的
}
}
}
return 0;
}
3.H-Tic Tac DREAMIN'_2026牛客寒假算法基础集训营3
题目复现

解题思路
题目没啥意思,注意精度就可以了,保留6位是不可以的
code
cpp
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=2e6+5;
#define endl '\n'
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
double xa, ya, xb, yb;
cin >> xa >> ya >> xb >> yb;
double ans = xa * yb - ya * xb;
double k = ya - yb;
const double f = 4.0;
if (k == 0) {
if (fabs(ans) == f) {
cout << "0.0000000000" << endl;
} else {
cout << "no answer" << endl;
}
} else {
double x1 = (f - ans) / k;
cout << fixed << setprecision(10) << x1 << endl;
}
return 0;
}
4.F-Energy Synergy Matrix_2026牛客寒假算法基础集训营3
题目复现

解题思路
在 2×n 网格的博弈中,小红和小紫轮流放置障碍(需保证起点到第 n 列仍连通),小红想最小化最终最短步数,小紫想最大化。博弈结束后剩余格子必为简单路,最短步数由 "至少 n-1 次向右移动" 和 "换行次数 r" 构成;因强制换行结构需占用 5 列,双方最优策略下每 5 列恰好产生 1 次换行,故 r=⌊n/5⌋,最终答案为 (n-1)+⌊n/5⌋。
code
cpp
#include<bits/stdc++.h>
using namespace std;
using ll= unsigned long long ;
const int N=2e6+5;
#define endl '\n'
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--){
ll n;
cin >> n;
cout << n - 1 + n / 5 << endl;
}
return 0;
}
5.I-01回文_2026牛客寒假算法基础集训营2
题目复现

解题思路
统计01的个数就可以,只要0的个数大于1,碰到零都是yes,只要一的个数大于一,碰到一都输出yes,否则就是no。
code
cpp
#include<bits/stdc++.h>
using namespace std;
using ll=long long ;
const int N=2e6+5;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
int cnt0=0,cnt1=0;
vector<string> a(n);
for(int i=0;i<n;i++){
cin>>a[i];
for(int j=0;j<m;j++){
if(a[i][j]=='0') cnt0++;
else cnt1++;
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(a[i][j]=='0'){
if(cnt0>=2) cout<<'Y';
else cout<<'N';
}else{
if(cnt1>=2) cout<<'Y';
else cout<<'N';
}
}
cout<<'\n';
}
}
return 0;
}
6.E-01矩阵_2026牛客寒假算法基础集训营2
题目复现

解题思路
题目给出了答案为 22的构造
类推一下答案为 3,4,5的构造:
cpp
00
01
000
011
010
0000
0111
0100
0101
00000
01111
01000
01011
01010
code
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
cout << "10"[min(i, j) & 1];
}
cout << endl;
}
}
三.本周总结
总体来说这周不错,下周还是继续好好加油吧,好好打牛客,还有cf晚上也要打,然后就是继续做一些dp的题目。