Codeforces Round #754 (Div. 2)C. Dominant Character(区间dp||find函数||硬做)

C. Dominant Character
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Ashish has a string s
of length n

containing only characters ‘a’, ‘b’ and ‘c’.

He wants to find the length of the smallest substring, which satisfies the following conditions:

Length of the substring is at least 2

'a' occurs strictly more times in this substring than 'b'
'a' occurs strictly more times in this substring than 'c' 

Ashish is busy planning his next Codeforces round. Help him solve the problem.

A string a
is a substring of a string b if a can be obtained from b

by deletion of several (possibly, zero or all) characters from the beginning and several (possibly, zero or all) characters from the end.
Input

The first line contains a single integer t
(1≤t≤105)

— the number of test cases. The description of test cases follows.

The first line of each test case contains a single integer n
(2≤n≤106) — the length of the string s

.

The second line of each test case contains a string s

consisting only of characters ‘a’, ‘b’ and ‘c’.

It is guaranteed that the sum of n
over all test cases does not exceed 106

.
Output

For each test case, output the length of the smallest substring which satisfies the given conditions or print −1

if there is no such substring.
Example
Input
Copy

3
2
aa
5
cbabb
8
cacabccc

Output
Copy

2
-1
3

Note

Consider the first test case. In the substring “aa”, ‘a’ occurs twice, while ‘b’ and ‘c’ occur zero times. Since ‘a’ occurs strictly more times than ‘b’ and ‘c’, the substring “aa” satisfies the condition and the answer is 2
. The substring “a” also satisfies this condition, however its length is not at least 2

In the second test case, it can be shown that in none of the substrings of “cbabb” does ‘a’ occur strictly more times than ‘b’ and ‘c’ each.

In the third test case, “cacabccc”, the length of the smallest substring that satisfies the conditions is 3

.

昨天晚上我看到这个题目,因为每个字符串之后跟这个串有关系,所以我们自然想到用区间dp,(现在我好像看啥都像区间dp,因为字符串很多题目前后都有连贯性所以可以使用dp的思想求解很多问题…)但是呢,我没有考虑最短串的长度一定<=7,遂gg,改了len<=7就过了,修改之前wa在第四个样例了,显示答案是191,(应该是爆掉了,我猜在len=191复杂度超了??)其实是-1(也就是找不到),遗憾,还是得多观察!官方题解跟我思路差不多(贴在下面了),就是两重for循环的顺序跟我的反了(其实都可…我感觉用区间dp更快一点…)还有一种方法就是find函数直接硬核查找所有情况:
在这里插入图片描述可是!!!这些所有都是建立在我们判断出7是最小串的最大长度的前提下完成的!!!我看了cf题解来证明一下:首先如果满足题给条件的话,那么分两种可能情况:一种就是a和a之间距离<=2的,也就是aa或aba,aca这三种;反之,满足条件的子串必须长“a??a??a??a…”这个样,也就是说aa之间夹杂的必须是两个其他字母(或b或c)否则就构建不出num(a)>num(b)&&num(a)>num©的串,因此就有了长度是4和7的这些情况
2种代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N =1e6+7 ; 
char a[N];
char b[N];
char c[N];
int main() 
{       int t ;
        cin>>t; 
        while(t--)
       {
//	    	memset(a,0,sizeof(a));
//       	memset(b,0,sizeof(b));
//       	memset(c,0,sizeof(c));
		   int chang ;
       	   cin>>chang ;
           string s; 
           cin>>s; 
           for(int i =0 ;i<s.size();i++)
         {
         	 if(s[i]=='a')
			 {
			 a[i]=1;
		     b[i]=0;
			 c[i]=0;
			 }
			 else if(s[i]=='b') {
			 a[i]=0;
		     b[i]=1;
			 c[i]=0;
			 }
			 else {
			 a[i]=0;
		     b[i]=0;
			 c[i]=1;}
		 }int ming = 0 ; 
          for(int len=2;len<=7;len++)//就是这个地方!
          {
           for(int kaishi= 0;kaishi<=chang-len;kaishi++)
           {
           	if(s[kaishi+len-1]=='a')a[kaishi]++; 
           	else if(s[kaishi+len-1]=='b')b[kaishi]++;
           	else c[kaishi]++; 
           	if(a[kaishi]>b[kaishi]&&a[kaishi]>c[kaishi])
           	{  
           	   cout<<len<<endl;
			   ming =1; 
			   break ; 	
			}
		   }if(ming==1)break ;
		  } if(ming==0)cout<<"-1"<<endl;
	   }
	return 0 ; 
```cpp
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl "\n"
#define int long long
const int N = 1e6 + 5;
int n;
string s;
int32_t main()
{
	IOS;
	int t;
	cin >> t;
	while(t--)
	{
		cin >> n >> s;
		int ans = 1e9;
		for(int i = 0; i < n; i++)
		{
			vector<int> f(3, 0);
			f[s[i] - 'a']++;
			for(int j = i + 1; j < min(n, i + 7); j++)//以防越界! 
			{
				f[s[j] - 'a']++;
				if(f[0] > f[1] && f[0] > f[2])
					ans = min(ans, j - i + 1);
			}
		}
		if(ans == 1e9)
		ans = -1;
		cout << ans << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值