1. 程式人生 > >Wannafly挑戰賽28 B-msc和mcc

Wannafly挑戰賽28 B-msc和mcc

題目大意:有一串長度為n的字串s,只包含’m’ ‘s’ 'c’三種字元,請你找出下標位置都不重複的msc和mcc的一段序列s[x,y] 求(x,y)的對數,即有多少個滿足條件的連續序列。

思路:將可能的msc和mcc在序列中出現的方式都列出來,共八種,用陣列next[x][y]表示位置為x的字母后第一次出現y的位置,然後去暴力列舉8種情況,取長度最短滿足的,計算數量累加答案。

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
typedef long long ll;
int n,nextp[maxn][30];
ll ans,tmp;  //注意答案要用long long 
char str[8][7]={"mscmcc","mmsccc","mmccsc","mmcscc","mccmsc","mcmcsc","msmccc","mcmscc"};
string s;
int main()
{
	cin>>n>>s;
	s=" "+s;
	for(int i='a';i<='z';i++){
		for(int j=n;j>0;j--){
			nextp[j-1][i-'a']=nextp[j][i-'a'];
			if(s[j]==char(i)) 
				nextp[j-1][i-'a']=j;
		}
	}
	
	ll pos=0;
	for(int i=1;i<=n;i++){
		tmp=inf; 
		for(int u=0;u<8;u++){
			pos=i-1;
			for(int v=0;v<6;v++){
				pos=nextp[pos][str[u][v]-'a'];
				if(pos==0) break;//找不到該種序列,遍歷下一種	 
			}
			if(pos!=0) 
				tmp=min(tmp,pos);//找到一種,更新tmp為最小 
		}
		if(tmp!=inf)
			ans+=n-tmp+1; 
	}
	cout<<ans<<endl;
}