CF1605 C. Dominant Character(思维)

题目链接


题意:

给定长度为 n ( 2 ≤ n ≤ 1 0 6 ) (2≤n≤10^6) (2n106) 的仅包含字符'a','b','c'的字符串,找到满足下列条件的最短字串,输出其长度。

  • 长度至少为2;
  • ‘a’出现的次数严格都大于’b’,'c’出现的次数。

思路:

仅包含三种字符,就使得只需要判断少量的情况,其他的情况可以划分为更小规模的问题。这是突破口。

如果一个字符串的长度为2,3,4,5,7时,需要判断其是否是满足条件的子串(可能满足);但是如果不是,那么其一定可以分解出长度为上述数字的子串是满足的。

比如:
长度为2:aa,本身满足
长度为3:aca,同上
长度为4:abca,同上
长度为5:abbca,同上
长度为6:abbcaa,最后三个字符满足,长度为3,可以在搜索所有长度为3的子串时找到。
长度为7:abbacca,本身满足
长度为8:abbaacca,前五个字符满足,长度为5,可以在搜索所有长度为5的子串时找到。
长度为9:abbacacac,第四到六个字符满足,长度为3,可以搜索在所有长度为3的子串时找到。

长度为 n … 其他长度的串都可以从中找出长度为2或3或4或5或7的满足子串。

所以,只需要判断长度为2,3,4,5,7的所有字串是否满足就可以了。

Code:

const int N = 1000010, mod = 1e9+7;
int T, n, m;
char a[N];
int cnta[N],cntb[N],cntc[N];

bool pd(int len)
{
    
    
	for(int i=1;i<=n-len+1;i++)
	{
    
    
		int cnt1 = cnta[i+len-1]-cnta[i-1];
		int cnt2 = cntb[i+len-1]-cntb[i-1];
		int cnt3 = cntc[i+len-1]-cntc[i-1];
		if(cnt1>cnt2&&cnt1>cnt3) return 1;
	}
	return 0;
}

int main(){
    
    
	Ios;
	
	cin>>T;
	while(T--)
	{
    
    
		cin>>n;
		for(int i=1;i<=n;i++){
    
    
			cin>>a[i];
			cnta[i]=cnta[i-1];
			cntb[i]=cntb[i-1];
			cntc[i]=cntc[i-1];
			if(a[i]=='a') cnta[i]++;
			else if(a[i]=='b') cntb[i]++;
			else cntc[i]++;
		}
		if(pd(2)) cout<<2<<"\n";
		else if(pd(3)) cout<<3<<"\n";
		else if(pd(4)) cout<<4<<"\n";
		else if(pd(5)) cout<<5<<"\n";
		else if(pd(7)) cout<<7<<"\n";
		else cout<<-1<<"\n";
	}
	
	return 0;
}

经验:

看到字符种类较少时,应该想到,较长的长度的串中 可能有 较短长度的子串 所具有的性质。

おすすめ

転載: blog.csdn.net/Mr_dimple/article/details/121479345