吃寿司 C++

题意:

东东和他的女朋友(幻想的)去寿司店吃晚餐(在梦中),他发现了一个有趣的事情,这家餐厅提供的 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
我们只需要计算在某一时刻两个栈内,12个数的最小值的两倍即为最大长度;注意,数字变换的时候需要清空栈。
以最后一个样例做解释:

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值