jzoj 3843. 尋找羔羊(agnus) (Standard IO)

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
12345678901234567890
總的子串個數爲10(10+1)/2=5510*(10+1)/2=55
其中s[16]s[1-6],s[410]s[4-10]的所有子串不合法,總答案減去6(6+1)/2+7(7+1)/2=496*(6+1)/2+7*(7+1)/2=49
s[46]s[4-6]中的所有子串被減了兩次,要加回3(3+1)/2=63*(3+1)/2=6
答案爲5549+6=1255-49+6=12

#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);
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章