2022牛客寒假算法基础集训营4 个人题解

2022牛客寒假算法基础集训营4 个人题解

比赛链接:2022牛客寒假算法基础集训营4

A题 R

题目大意:

小红拿到了一个长度为 n 的字符串,该字符串仅由大写字母组成。
小红很喜欢红色(用R字母表示),但她非常讨厌紫色(用P字母表示)。
她想取一个连续子串,该子串包含至少 kR字符,且不能包含P字符。
你能告诉她有多少合法的方案可以取到吗?
注:只要连续子串的起始位置或终止位置不同,我们就认为是两个不同的方案。

思路解析:

双指针

AC代码:

#include <algorithm> #include<bits/stdc++.h> #include <cmath> using namespace std; typedef long long ll; typedef unsigned long long ull; #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #define endl '\n' #define pii pair<int,int> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); const int maxn=1e6+5; char s[maxn]; int sum[maxn]; int a[maxn]; int main(){ IOS int n,k; cin>>n>>k; cin>>s+1; int top=n+1; for(int i=1;i<=n;i++){ if(s[i]=='P')sum[i]=sum[i-1]+1; else sum[i]=sum[i-1]; int now=n-i+1; if(s[now]!='P')a[now]=top; else top=now; } int tp=1,sum=0; ll ans=0; for(int i=1;i<=n;i++){ if(s[i]=='P'){ sum=0; tp=i+1; } if(s[i]=='R'){ sum++; while(sum>=k&&tp<i+1){ ans+=abs(i-a[i]); sum-=(s[tp]==s[i]); tp++; } } } while(tp<n+1){ tp++; if(s[tp]=='R')tp+=1,sum-=1; if(sum>=k)ans+=1; } cout<<ans<<endl; }

B题 进制

题目大意:链接:https://ac.nowcoder.com/acm/contest/23479/B

来源:牛客网

小红拿到了一个长度为 n 的数字串 s(只有 0 9 这十种字符),她有 q 次以下两种操作:

第一种: 输入1xy,修改第 x 个字符为 y ,即令sx=y

第二种: 输出 2xy ,代表查询区间 [x,y],该区间子串所能表示的某进制的最小值(进制必须合法,且必须是二进制到十进制之间,可以包含前导零),对 1000000007 取模。

思路解析:

十颗线段树,对每一种进制建树维护

(贴一份队友聚聚的代码)AC代码:

#include <bits/stdc++.h> #define debug(x) cout << #x << "=" << x << '\n'; #define ls u << 1 #define rs u << 1 | 1 #define ll long long using namespace std; typedef pair<int, int> PII; const int N = 1e5 + 10, mod = 1000000007; int n, q; char s[N]; ll qmi(ll a, ll b) { if (!a) return 0; ll res = 1; while(b) { if(b & 1) res = res * a % mod; b >>= 1; a = a * a % mod; } return res % mod; } struct segment_tree { struct node { int l, r; int v, maxv; ll val; int len, jz; } tr[N * 4]; void pushup(node &u, node &l, node &r) { int t = l.jz; u.jz = l.jz; u.len = l.len + r.len; u.maxv = max(l.maxv, r.maxv); u.val = (l.val * qmi(t, r.len) % mod + r.val) % mod; } void pushup(int u) { pushup(tr[u], tr[ls], tr[rs]); } void build(int u, int l, int r, int k) { if(l == r) tr[u] = {l, r, s[l] - '0', s[l] - '0', s[l] - '0', 1, k}; else { tr[u] = {l, r}; int mid = l + r >> 1; build(ls, l, mid, k), build(rs, mid + 1, r, k); pushup(u); } } void modify(int u, int x, int v) { if(tr[u].l == x && tr[u].r == x) { int k = tr[u].jz; tr[u] = {x, x, v, v, v, 1, k}; } else { int mid = tr[u].l + tr[u].r >> 1; if(x <= mid) modify(ls, x, v); else modify(rs, x, v); pushup(u); } } node query(int u, int l, int r) { if(tr[u].l >= l && tr[u].r <= r) return tr[u]; int mid = tr[u].l + tr[u].r >> 1; if(r <= mid) return query(ls, l, r); if(l > mid) return query(rs, l, r); node res, left = query(ls, l, r), right = query(rs, l, r); pushup(res, left, right); return res; } } tree[11]; void solve() { cin >> n >> q; cin >> (s + 1); for(int i = 2; i <= 10; i++) { tree[i].build(1, 1, n, i); } while(q--) { int op, x, y; cin >> op >> x >> y; if(op == 1) { for(int i = 2; i <= 10; i++) tree[i].modify(1, x, y); } else { auto tmp = tree[2].query(1, x, y); int mx = tmp.maxv; cout << tree[mx + 1].query(1, x, y).val << '\n'; } } } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); // int T;cin>>T;while(T--) solve(); }

C题 蓝彗星

题目大意:

给出 n 颗彗星以及他们的颜色,蓝或者红,持续时间和开始时间,问有多少秒只能看到蓝彗星看不到红彗星

思路解析:

蓝红分别差分即可

AC代码:

#include<bits/stdc++.h> #include <cmath> using namespace std; typedef long long ll; typedef unsigned long long ull; #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #define endl '\n' #define pii pair<int,int> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); const int maxn=1e6+5; int a[maxn]; char col[maxn]; int b[maxn],r[maxn]; int main(){ IOS int n,t; cin>>n>>t; cin>>col+1; for(int i=1;i<=n;i++){ cin>>a[i]; if(col[i]=='B')b[a[i]]++,b[a[i]+t]--; else r[a[i]]++,r[a[i]+t]--; } int x=0,y=0; ll ans=0; for(int i=1;i<=200005;i++){ x+=b[i]; y+=r[i]; if(x&&y==0)ans++; } cout<<ans<<endl; }

D题 雪色光晕

题目大意:

二维坐标中,给出小红和小果的坐标,每一秒给出一个方向向量,并且小红按照它移动,问在移动过程中,两个人的最短距离是多少

思路解析:

基础二维几何,点到线段的距离

AC代码:

//代码太长我就不放了hh

E题 真假签到题

题目大意:

给出以下代码:

long long f(long long x){ if(x==1)return 1; return f(x/2)+f(x/2+x%2); }

给出x,求f(x)

思路解析:

通过观察,我们发现f(x)=x,输出x即可

AC代码:

#include<bits/stdc++.h> #include <cmath> using namespace std; typedef long long ll; typedef unsigned long long ull; #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #define endl '\n' #define pii pair<int,int> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); const int maxn=1e6+5; long long f(long long x){ if(x==1)return 1; return f(x/2)+f(x/2+x%2); } int main(){ IOS ll n; cin>>n; cout<<n<<endl; }

F题 小红的记谱法

题目大意:

给出两种记谱方式,给出第二种,写出其对应的第二种(是不是觉得小飞龙没有讲清楚题意?主要是题面太长难解释自行观看hh)

思路解析:

计数,模拟即可

AC代码:

#include<bits/stdc++.h> #include <cmath> using namespace std; typedef long long ll; typedef unsigned long long ull; #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #define endl '\n' #define pii pair<int,int> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); const int maxn=1e6+5; map<char ,int>q; int main(){ IOS string s; cin>>s; int x=0,y=0; q['C']=1; q['D']=2; q['E']=3; q['F']=4; q['G']=5; q['A']=6; q['B']=7; for(int i=0;i<s.size();i++){ if(s[i]=='<')x++; else if(s[i]=='>')y++; else { int now=q[s[i]]; cout<<now; if(x>y){ for(int i=y;i<x;i++)cout<<"."; } else if(y>x)for(int i=x;i<y;i++)cout<<"*"; } } }

G题 子序列权值乘积

题目大意:

求出数组中非空子序列的权值的乘积是多少

权值定义为:

思路解析:

我们发现序列顺序对于序列的权值是没有影响的,我们可以先排序与,枚举每个值作为所选序列的最大值/最小值,分别计算其对于答案的贡献。

作为最小值的贡献:a[i]2i1
作为最大值的贡献:a[i]2ni

由于指数较大,所以使用欧拉降幂

AC代码:

#include<bits/stdc++.h> #include <cmath> using namespace std; typedef long long ll; typedef unsigned long long ull; #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #define endl '\n' #define pii pair<int,int> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); const int maxn=1e6+5; const int mod=1e9+7; ll a[maxn]; ll ans=1; ll ksm(ll a,ll b,ll mod){ ll ans=1,base=a%mod; while(b){ if(b&1) ans=ans*base%mod; base=base*base%mod; b>>=1; } return ans%mod; } ll oljm(ll m,ll k,ll n){ if(m%mod==0)return 0; ll p=ksm(k,n,mod-1); return ksm(m,p,mod)%mod; } int main(){ IOS int n; cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; sort(a+1,a+n+1); for(int i=1;i<=n;i++){ ans*=oljm(a[i],2,i-1); ans%=mod; ans*=oljm(a[i],2,n-i); ans%=mod; } cout<<ans%mod<<endl; }

H题 真真真真真签到题

题目大意:

小红和紫被困在一个正方体的内部。紫先选择了一个位置,然后小红选择一个位置。紫希望离小红尽可能近,小红希望离紫尽可能远。两人都会选择最优策略。
已知她们最终的距离为 x 。小红想知道正方体的体积是多少?

思路解析:

因为紫先选,所以他会选择正方体的中心来保证最优,然后小红要离中点尽量远,所以选择正方体的顶点

AC代码:

#include<bits/stdc++.h> #include <cmath> using namespace std; typedef long long ll; typedef unsigned long long ull; #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #define endl '\n' #define pii pair<int,int> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); const int maxn=1e6+5; int main(){ double x; cin>>x; x=x*2/sqrt(3); printf("%0.6f",x*x*x); }

I题 爆炸的符卡洋洋洒洒

题目大意:

小红有n张卡,每张卡消耗为ai,威力为bi,问能选择最大的威力和是多少

特别的,必须保证所选卡的消耗和为k的倍数

思路解析:

01背包的变形版本

我们只需要把转移改为f[i][j]=max(f[i][j],f[i1][(jv[i]+m)%m]+w[i])

特别的我们需要判断是否有方案可以转移才能够向下转移

AC代码:

#include<bits/stdc++.h> #include <cmath> using namespace std; typedef long long ll; typedef unsigned long long ull; #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #define endl '\n' #define pii pair<int,int> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); const int maxn=1005; ll f[maxn][maxn]; ll v[maxn], w[maxn]; int n, m; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> v[i] >> w[i]; v[i]%=m; f[i][v[i]]=w[i]; } for (int i = 1; i <= n; i++) { for (int j = 0; j < m; j++) { f[i][j] = max(f[i][j],f[i-1][j]); if(f[i - 1][(j - v[i]+m)%m]) f[i][j] = max(f[i][j], f[i - 1][(j - v[i]+m)%m] + w[i]); } } if(f[n][0]==0)cout<<-1<<endl; else cout<<f[n][0]<<endl; }

J题 区间合数的最小公倍数

题目大意:

[l,r] 区间所有合数的最小公倍数是多少

思路解析:

将区间内每个数分解质因数,那么每一个质因子取最大值即为乘积的质因子,然后计算即可

AC代码:

#include<bits/stdc++.h> #include <cmath> using namespace std; typedef long long ll; typedef unsigned long long ull; #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #define endl '\n' #define pii pair<int,int> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); const int maxn=1e6+5; const int mod=1e9+7; int st[maxn],prime[maxn],tot; ll ksm(ll a,ll b){ ll ans=1,base=a%mod; while(b){ if(b&1) ans=ans*base%mod; base=base*base%mod; b>>=1; } return ans; } void get_primes(int n){ for(int i=2;i<=n;i++){ if(!st[i])prime[++tot]=i; for(int j=1;prime[j]<=n/i;j++){ st[prime[j]*i]=1; if(i%prime[j]==0)break; } } } int p[maxn]; void divide(int x) { for (int i = 2; i <= x / i; i ++ ) if (x % i == 0) { int s = 0; while (x % i == 0) x /= i, s ++ ; p[i]=max(p[i],s); //cout << i << ' ' << s << endl; } if (x > 1) p[x]=max(p[x],1); } int main(){ IOS get_primes(30505); int l,r; cin>>l>>r; if(l==1)l++; ll ans=1; int sum=0; for(int i=l;i<=r;i++){ if(st[i]){ divide(i); sum++; } } if(sum==0)cout<<-1<<endl; else { for(int i=1;i<=tot;i++){ ans*=ksm(prime[i],p[prime[i]])%mod; ans%=mod; } cout<<ans<<endl; } }

K题 小红的真真假假签到题题

题目大意:

小红拿到了一个正整数 x 。她想构造一个正整数 y,满足以下性质:

  • yx 的倍数,且 xy 不能相等。
  • x 在二进制表示下(为一个01串)是 y 的二进制表示的一个子串。且 xy 的二进制表示的1的个数不能相同。
  • y 必须为不超过 1019的正整数。

思路解析:

很多种构造方式,小飞龙的方法:

110>110110
1011>10111011
10>1010

这样的方式扩大

AC代码:

#include<bits/stdc++.h> #include <cmath> using namespace std; typedef long long ll; typedef unsigned long long ull; #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #define endl '\n' #define pii pair<int,int> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); const int maxn=1e6+5; int main(){ IOS ll x; cin>>x; ll op=x; ll now=x; int sum=0; while(now){ now/=2; sum++; } x<<=sum; x+=op; cout<<x<<endl; }

L题 在这冷漠的世界里光光哭哭

题目大意:

思路解析:

AC代码:

https://files.cnblogs.com/files/blogs/696109/tt.rar?t=1691327061&download=true

推广一波小飞龙博客:戳这里@不会飞的小飞龙


__EOF__

本文作者不会飞的小飞龙
本文链接https://www.cnblogs.com/xiaofeilong7816/p/15838958.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   不会飞的小飞龙  阅读(358)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
Live2D
欢迎阅读『2022牛客寒假算法基础集训营4 个人题解』
点击右上角即可分享
微信分享提示