W String Problem

本文详细解析了一道编程难题,旨在找到给定字符串中满足特定条件的最长W形子串。通过引入结构体和遍历策略,作者巧妙地解决了问题,为读者提供了深入理解代码逻辑和字符串操作的宝贵见解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

W String

Problem code: WSTRING

Kira likes to play with strings very much. Moreover he likes the shape of 'W' very much. He takes a string and try to make a 'W' shape out of it such that each angular point is a '#' character and each sides has same characters. He calls them W strings.

For example, the W string can be formed from "aaaaa#bb#cc#dddd" such as:

    a
     a             d
      a     #     d
       a   b c   d
        a b   c d
         #     #

He also call the strings which can generate a 'W' shape (satisfying the above conditions) W strings.

More formally, a string S is a W string if and only if it satisfies the following conditions (some terms and notations are explained in Note, please see it if you cannot understand):

  • The string S contains exactly 3 '#' characters. Let the indexes of all '#' be P1 < P2 < P3 (indexes are 0-origin).
  • Each substring of S[0, P1−1], S[P1+1, P2−1], S[P2+1, P3−1], S[P3+1, |S|−1] contains exactly one kind of characters, where S[a, b] denotes the non-empty substring from a+1th character to b+1th character, and |S| denotes the length of string S (See Note for details).

Now, his friend Ryuk gives him a string S and asks him to find the length of the longest W string which is a subsequence of S, with only one condition that there must not be any '#' symbols between the positions of the first and the second '#' symbol he chooses, nor between the second and the third (here the "positions" we are looking at are in S), i.e. suppose the index of the '#'s he chooses to make the W string are P1, P2, P3 (in increasing order) in the original string S, then there must be no index i such that S[i] = '#' where P1 < i < P2 or P2 < i < P3.

Help Kira and he won't write your name in the Death Note.

Note:

For a given string S, let S[k] denote the k+1th character of string S, and let the index of the character S[k] be k. Let |S| denote the length of the string S. And a substring of a string S is a string S[a, b] = S[a] S[a+1] ... S[b], where 0 ≤ a ≤ b < |S|. And a subsequence of a string S is a string S[i0] S[i1] ... S[in−1], where 0 ≤ i0 < i1 < ... < in−1 < |S|.

For example, let S be the string "kira", then S[0] = 'k', S[1] = 'i', S[3] = 'a', and |S| = 4. All of S[0, 2] = "kir", S[1, 1] = "i", and S[0, 3] = "kira" are substrings of S, but "ik", "kr", and "arik" are not. All of "k", "kr", "kira", "kia" are subsequences of S, but "ik", "kk" are not.

From the above definition of W string, for example, "a#b#c#d", "aaa#yyy#aaa#yy", and "o#oo#ooo#oooo" are W string, but "a#b#c#d#e", "#a#a#a", and "aa##a#a" are not.

Input

First line of input contains an integer T, denoting the number of test cases. Then T lines follow. Each line contains a string S.

Output

Output an integer, denoting the length of the longest W string as explained before. If S has no W string as its subsequence, then output 0.

Constraints

  • 1 ≤ T ≤ 100
  • 1 ≤ |S| ≤ 10000 (104)
  • S contains no characters other than lower English characters ('a' to 'z') and '#' (without quotes)

Example

Input:
3
aaaaa#bb#cc#dddd
acb#aab#bab#accba
abc#dda#bb#bb#aca

Output:
16
10
11

Explanation

In the first case: the whole string forms a W String.

In the second case: acb#aab#bab#accba, the longest W string is acb#aab#bab#accba

In the third case: abc#dda#bb#bb#aca, note that even though abc#dda#bb#bb#aca (boldened characters form the subsequence) is a W string of length 12, it violates Ryuk's condition that there should not be any #'s inbetween the 3 chosen # positions. One correct string of length 11 is abc#dda#bb#bb#aca


/*思路:这题真坑,刚刚开始看的时候,感觉很简单,没仔细看直接上,后来发现子集的定义理解错了
,改过来又超时,坑,
我的思路:将没两个‘#’直接的字符用结构体保存,并且保存最大值,最后直接每三个'#'查找一次
取最大值,我将第一个'#'之前的用结构体b表示,那么每次后移就只要加上下一个的所有字符,取最大值
同理最后一个用字符c表示,只要减去前一个'#'的区间字符,这样节省了时间*/
#include<iostream>
#include<cstring>
using namespace std ;
typedef struct infor
{
    int a[27] ;
    int max ;
}infor;
infor m[10003] ;
int main(void)
{
    int  t;
    cin >> t ;
    while(t--)
    {
        char s[10003] ;
        cin >> s ;
        int i ,j , k = 0  ,len = strlen(s) ;
        for( i = 0 ; i < 10003 ;i ++){
            memset(m[i].a , 0 ,sizeof(m[i].a)) ;
            m[i].max = 0 ;
        }
        for( i = 0 ; i < len ;i ++){
            if(s[i]=='#'){
                for( j = 0; j <27 ;j ++)
                    m[k].max = m[k].max < m[k].a[j]?m[k].a[j]:m[k].max ;
                k++;
            }
            else
                m[k].a[s[i]-'a'] ++ ;
        }
        for( j = 0; j <27 ;j ++)
            m[k].max = m[k].max < m[k].a[j]?m[k].a[j]:m[k].max ;
        k++;

        if(k<3)
        {
            cout<<"0"<<endl;
            continue ;
        }
        infor b , c ;
        for( j = 0 ; j < 27 ;j ++)
        {
            c.a[j] = m[0].a[j] ;
            c.max = m[0].max ;
            memset(b.a , 0 ,sizeof(b.a));
            b.max = 0 ;
        }

        for( i = 3 ; i < k ; i++)
        {
            for( j = 0 ; j < 27 ; j ++){
                b.a[j]+=m[i].a[j] ;
                b.max = b.max < b.a[j] ? b.a[j] : b.max ;
            }
        }
        int sum = 0 , max = 0 ;
        for( i = 3 ; i < k ; i++)
        {
            //cout<<b.max << " "<<c.max <<endl;

            if(!(b.max && m[i-1].max&& m[i-2].max&&c.max)){
                b.max = 0 ;
                for( j = 0 ; j < 27 ;j ++)
                {
                    c.a[j] += m[i-2].a[j] ;
                    c.max = c.max < c.a[j] ? c.a[j] : c.max ;
                    b.a[j] -=m[i].a[j] ;
                    b.max = b.max < b.a[j] ? b.a[j] : b.max ;
                }
                continue ;
            }
            sum = b.max + m[i-1].max + m[i-2].max +c.max ;
            max = max < sum ? sum : max ;
            b.max = 0 ;
            for( j = 0 ; j < 27 ;j ++)
            {
                c.a[j] += m[i-2].a[j] ;
                c.max = c.max < c.a[j] ? c.a[j] : c.max ;
                b.a[j] -=m[i].a[j] ;

                b.max = b.max < b.a[j] ? b.a[j] : b.max ;
            }
        }
        if(max)
            cout<<max + 3<<endl;
        else
            cout<<"0"<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值