Description
給定一個由小寫字母組成的字符串,尋找包含“agnus”(羔羊)的子串的個數。注意:當且僅當兩個子串的起始位置和終點不同時,這兩個子串屬於不同的子串。
Input
只有一個字符串,表示題中所述的字符串。
Output
僅一個數字,表示滿足題意的子串個數。
Sample Input
agnusbgnus
Sample Output
6
【樣例解釋】
6個子串分別是:agnus、agnusb、agnusbg、agnusbgn、agnusbgnu、agnusbgnus。
Data Constraint
對於 40%的數據,字符串長度<=1000
對於 100%的數據,字符串長度<=30000
//written by zzy
題目大意:
給你個字符串,求這個串中有多少個子串(字母連續)中有agnus
題解:
容斥,用總的所有子串個數減去不合法的子串個數
例如:S爲
XXagnusXXX
總的子串個數爲
其中,的所有子串不合法,總答案減去
但中的所有子串被減了兩次,要加回
答案爲
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 30005
using namespace std;
int i,j,n=0,m,p,l,ans,re;
int f[N];
char s[N];
int num(int x) {
return x*(x+1)/2;
}
int main()
{
scanf("%s",s);
l=strlen(s);
ans=num(l);
for (i=0;i<l;i++)
if (s[i]=='a'&&s[i+1]=='g'&&s[i+2]=='n'&&s[i+3]=='u'&&s[i+4]=='s')
f[++n]=1,i+=4,re++;
else f[++n]=0;
p=0;
for (i=1;i<=n;i++)
if (f[i]==1) {
if (p==0) ans-=num(i+3);
else ans-=num(i-p+7);
p=i;
}
ans-=num(n-p+4);
ans+=re*6;
printf("%d",ans);
}