字符串统计
字符串统计
内存限制:512MB
时间限制:1.000s
题解:
30分做法
暴力枚举长度大于等于 3的子串,每个子串循环查找
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
using namespace std;
const int N=1e5+10;
const int mod=1e6+3;
int main()
{ios::sync_with_stdio(false);cin.tie(0);freopen("string.in","r",stdin);freopen("string.out","w",stdout);int n;string s;cin>>n>>s;s=" "+s;ll ans=0;for(int len=3;len<=n;len++){for(int i=1;i+len-1<=n;i++){int j=i+len-1;int x=0,y=0;for(int k=i;k<=j;k++){if(s[k]=='H') x++;else y++;}if(x==1||y==1) ans++;}}cout<<ans;return 0;
}
60分做法
暴力枚举长度大于等于 3的子串,前缀和O(1)时间查找
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
using namespace std;
const int N=1e5+10;
const int mod=1e6+3;
int main()
{ios::sync_with_stdio(false);cin.tie(0);freopen("string.in","r",stdin);freopen("string.out","w",stdout);int n;string s;cin>>n>>s;s=" "+s;ll ans=0;vector<int> cnt(n+10);for(int i=1;i<=n;i++) cnt[i]=cnt[i-1]+(s[i]=='H');for(int len=3;len<=n;len++){for(int i=1;i+len-1<=n;i++){int j=i+len-1;if(cnt[j]-cnt[i-1]==1||cnt[j]-cnt[i-1]==j-i) ans++;}}cout<<ans;return 0;
}
100分做法
我们用一个数组记录每一个 G所在的位置,再用一个数组记录每一个 H所在的位置。
例如样例中, a数组中存 G所在的位置为 1,3,5, b数组中存 H所在的位置为 2,4。
遍历整个字符串,求以当前字符为中心的满足条件的子串数量,若当前字符为 G,则在 a数组中查找
当前字符左右两侧第一个 G的位置,记作 l,r,则 [l+1,r-1]就是只包含一个 G的范围。
- 若找到的区间长度小于 3,则不记录。
- 若找到的区间长度大于等于 3,根据区间范围内 G两侧 H的数量,计算子串数量
- 对于 H同样操作。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
using namespace std;
const int N=5e5+10;
const int mod=1e6+3;
int a[N],b[N],cnt,tot;
int main()
{ios::sync_with_stdio(false);cin.tie(0);freopen("string.in","r",stdin);freopen("string.out","w",stdout);int n;string s;cin>>n>>s;s=" "+s;a[++cnt]=0,b[++tot]=0;for(int i=1;i<=n;i++){if(s[i]=='G') a[++cnt]=i;else b[++tot]=i;}a[++cnt]=n+1,b[++tot]=n+1;ll ans=0;for(int i=2;i<cnt;i++){int l=a[i-1]+1;int r=a[i+1]-1;int p=a[i];if(r-l+1<3) continue;ll x=p-l;ll y=r-p;if(x>1) ans+=x-1;if(y>1) ans+=y-1;if(x>=1&&y>=1) ans+=x*y;}for(int i=2;i<tot;i++){int l=b[i-1]+1;int r=b[i+1]-1;int p=b[i];if(r-l+1<3) continue;ll x=p-l;ll y=r-p;if(x>1) ans+=x-1;if(y>1) ans+=y-1;if(x>=1&&y>=1) ans+=x*y;}cout<<ans;return 0;
}