题意:
东东和他的女朋友(幻想的)去寿司店吃晚餐(在梦中),他发现了一个有趣的事情,这家餐厅提供的 n 个的寿司被连续的放置在桌子上 (有序),东东可以选择一段连续的寿司来吃,东东想吃鳗鱼,但是东妹想吃金枪鱼。核 平 起 见,他们想选择一段连续的寿司(这段寿司必须满足金枪鱼的数量等于鳗鱼的数量,且前一半全是一种,后一半全是另外一种)我们用1代表鳗鱼,2代表金枪鱼。
比如,[2,2,2,1,1,1]这段序列是合法的,[1,2,1,2,1,2]是非法的。因为它不满足第二个要求。
东东希望你能帮助他找到最长的一段合法寿司,以便自己能吃饱。
Input
第一行:一个整数n(2≤n≤100000),寿司序列的长度。
第二行:n个整数(每个整数不是1就是2,意义如上所述)
Output
一个整数(代表东东可以选择的最长的一段连续的且合法的寿司)
Examples
Input
7
2 2 2 1 1 2 2
Output
4
Input
6
1 2 1 2 1 2
Output
2
Input
9
2 2 1 1 1 2 2 2 2
Output
6
思路:
假设我们有两个栈,一个压1
,一个压2
;
我们只需要计算在某一时刻两个栈内,1
和2
个数的最小值的两倍即为最大长度;注意,数字变换的时候需要清空栈。
以最后一个样例做解释:
2 2 1 1 1 2 2 2 2
stack1
作为1
的栈,stack2
作为2
的栈;
首先是2,因为前面没有数 ,所以直接压入stack2;
stack1
stack2—> 2
接下来 还是2,与前一个数相同,直接压入
stack1
stack2—> 2 2
然后是1,与前一个数不同,这时候要统计答案,
ans=min(stack1.size(),stack2.size())*2=0;
然后当前所属栈清空,然后加入1;
stack1 —> 1
stack2—>2 2
然后
stack1 —>1 1
stack2—>2 2
然后
stack1 —>1 1 1
stack2—>2 2
接下来是2,与前一个数不同,更新答案
ans=min(stack1.size(),stack2.size())*2=4;
然后清空2的栈,加入2;
stack1 —>1 1 1
stack2—>2
…
直到最后都是2,直接入栈
stack1 —>1 1 1
stack2—>2 2 2 2
最后在统计答案
ans=min(stack1.size(),stack2.size())*2=6;
因为我们自始至终都只用了stack的size,所以我们使用个map存储当前元素所在栈的size即可;
具体看代码
代码:
#include <cstdio>
#include <map>
#include <algorithm>
using namespace std;
const int maxn=100005;
int a[maxn];
int n;
map<int,int> mp; //存 1 2栈的元素
int pre;//前驱
int ans; //答案
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
pre=ans=0; //前驱和答案全是0
for(int i=1;i<=n;i++)
{
if(pre==0) //没有前驱是第一个元素 直接压栈
{
mp[a[i]]++; //size+1
pre=a[i]; //前驱
}
else
{
if(a[i]==pre) //和前驱一样 直接进去
mp[a[i]]++; //size+1
else
{ //和前驱不一样
ans=max(ans,2*min(mp[1],mp[2])); //更新答案
mp[a[i]]=1; //重新开始加入
pre=a[i]; //前驱
}
}
}
ans=max(ans,2*min(mp[1],mp[2])); //最后在统计一下
printf("%d",ans);
return 0;
}