CHEFSIGN: 大厨与符号序列
题目描述
大厨昨天捡到了一个奇怪的字符串 s,这是一个仅包含‘<’、‘=’和‘>’三种比较符号的字符串。
记字符串长度为 N,大厨想要在字符串的开头、结尾,和每两个字符之间插入一个正整数,共
N + 1 个数。大厨希望插入数字之后,这些比较符号所表达的含义是正确的。举个例子,如果
在‘<’前后分别插入 a 和 b,那么应当有 a < b。对于‘=’和‘>’也是类似的。
大厨可以在 [1, P] 中任意选择数字插入,同一个数也可以被插入到多个位置。
请你帮大厨计算 P 的最小取值可以是多少。
输入格式
输入的第一行包含一个整数 T,代表测试数据的组数。接下来是 T 组数据。
每组数据仅有一行,包含一个字符串 s。保证字符串仅包含‘<’、‘=’和‘>’三种字符。
输出格式
对于每组数据,输出一行,包含一个整数,代表 P 的最小取值。
数据范围和子任务
? 1 ≤ T, N ≤ 105
? 1 ≤ 每组数据中 N 之和 ≤ 106
子任务 1(30 分):
? 1 ≤ T, N ≤ 103
? 1 ≤ 每组数据中 N 之和 ≤ 104
子任务 2(70 分):
? 无附加限制
样例数据
输入
4
<<<
<><
<=>
<=<
输出
4
2
2
3
样例解释
下面对于每组数据分别给出一种可行的插入整数的方案:
? 1 < 2 < 3 < 4
? 1 < 2 > 1 < 2
? 1 < 2 = 2 > 1
? 1 < 2 = 2 < 3
首先,“=”可以完全忽略,我们需要的只有“>”和“<”号。让我们来考虑一下:
如果只有"<",那答案是什么呢?显然,是串的长度+1;
如果只有">",那答案是什么呢?显然,也是串的长度+1;
但是,现在两种都有,怎么办?显然,原串可拆分成若干单调子串。假设第一个符号前数为a1,假设<和>的交界处数分别为a2,a3,a4……,ak-1。最后一个符号后为ak。
则我们要求的就是max(abs(ai-aj)){1<=i,j<=k}。若将a数组投影至二位平面上,则是这样的:
显然,所有的abs(Ai-Ai-1)都是取决于最大的abs(Ai-Ai-1) {这里很关键,可以这样想:将上图看作一段段绳子,最长的那一段绳子一定有方法能够把其他都盖住(很抽象)},而abs(Ai-Ai-1)也要尽可能越小越好,但仍然需要最大,则以1为单位长度,则abs(Ai-Ai-1)则为从第i-1个折点到第i个折点的字符串长度。问题也就变成求解最长连续单调的序列的长度。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<string> 6 using namespace std; 7 int main(){ 8 int T; scanf("%d",&T); 9 string s; 10 for (; T; T--){ 11 cin>>s; int len=s.size(),las=0,cnt=0,ans=0; 12 for (int i=0; i<len; i++) if (s[i]!=‘=‘){ 13 if (s[i]==s[las]) las=i,cnt++; 14 else las=i,ans=max(ans,cnt),cnt=1; 15 } 16 ans=max(cnt,ans); 17 ans++; 18 cout<<ans<<endl; 19 } 20 return 0; 21 }