牛客刷题日记
小红的环形字符串(STL)
题意:
字符串首尾相连,相邻字符串相消,求最多能消除的字符个数
思路:
链表模拟,从左到右遍历将中间的消灭,再消灭左右两边
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void solve(){
int n;
string s;
cin>>n>>s;
list<char> q;
ll ans=0;
for(int i=0;i<s.size();i++){
if(!q.empty()){
if(q.back()==s[i])ans+=2,q.pop_back();
else q.push_back(s[i]);
}
else q.push_back(s[i]);
}
while(q.size()>1&&q.front()==q.back()){
ans+=2;
q.pop_back();
q.pop_front();
}
cout<<ans;
}
小红的子串(滑动窗口)
题意:
小红拿到了一个长度为n的字符串,她准备选取一段子串,满足该子串中字母的种类数量在[l,r]之间。小红想知道,一共有多少种选取方案?
思路:
三指针,一个指针扫描左端点,一个指针维护第一个大于等于l的右端点的值,一个指针维护第一个大于r的右端点的值 一个数dl维护到达右端点左指针时字母种类数量,一个dr维护右端点右指针字母种类数量,每次记录右端点的取值长度即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void solve(){
int n,L,R;
cin>>n>>L>>R;
string s;
cin>>s;
int dl=0,dr=0;
vector<int> cl(26),cr(26);
ll ans=0;
for(int i=0,j=0,k=0;i<n;i++){
while(j<n&&dl<L){
if(cl[s[j]-'a']++==0)dl++;
j++;
}
if(dl<L)break;
while(k<n&&dr<=R){
if(cr[s[k]-'a']++==0)dr++;
k++;
}
if(dr<=R)ans+=k-j+1;
else ans+=k-j;
if(cl[s[i]-'a']--==1)dl--;
if(cr[s[i]-'a']--==1)dr--;
}
cout<<ans<<'\n';
}
回文权值和
定义一个字符串的权值为:长度为3的回文子串的数量。求长度为n的、仅由小写字母组成的所有字符串的权值之和。答案对1e9+7取模。
提示:共有 $ 26^n $ 个字符串。
思路:
长度为3的回文串取法有26*26种,位置有(n-2)种方法,其他位置放法有 $26^{n-3} $ 种,答案为 $ (n-2) \cdot 26 \cdot 26 \cdot 26^{n-3} $
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ll ksm(ll a,ll b){
ll ans=1;
for(;b;b>>=1){
if(b&1)ans=(ans%mod*a%mod)%mod;
a=(a%mod*a%mod)%mod;
}
return ans;
}
void solve(){
ll n;
cin>>n;
if(n<3){
cout<<0;
return;
}
cout<<((n-2)%mod*ksm(26,n-1)%mod)%mod;
}
This post is licensed under CC BY 4.0 by the author.