浙江大学考研机试题——一端进,两端出

题目描述

给定一个输入受限的双端队列(即一个端点允许插入和删除,另一个端点只允许删除的双端队列)和一个长度为 N N N 的插入序列。

插入序列中的元素两两不同。

你需要将插入序列中的元素按顺序依次插入到给定队列中。

在插入过程中和插入完成后的任意时刻,你可以随时删除队列中的现有元素(如果有的话)。

将所有元素按删除顺序进行排列可以得到删除序列。

现在,给定 K K K 个删除序列,对于每个删除序列,请你判断其能否通过给定插入序列得到。

输入格式

第一行包含两个整数 N , K N,K N,K

第二行包含 N N N 个不同的整数,表示插入序列。

接下来 K K K 行,每行包含一个删除序列,保证每个删除序列都是给定插入序列的一个排列。

输出格式

每个删除序列,输出一行答案,如果该删除序列可以通过给定插入序列得到,则输出 yes,否则输出 no

数据范围
1 1 1 N N N 1 0 5 10^{5} 105,
1 1 1 K K K 10 10 10,
序列中元素的取值范围 [ 1 1 1, 1 0 9 10^9 109]。

输入样例:

5 4
10 2 3 4 5
10 3 2 5 4
5 10 3 2 4
2 3 10 4 5
3 5 10 4 2

输出样例:

yes
no
yes
yes

我们先来模拟一下样例:
首先,我们的插入序列是10 2 3 4 5,第一个删除序列是10 3 2 5 4,用 [ ] 表示在队列里的元素,先入队 [10],删除序列的首元素是10,我们可以直接出队,在入队 [2 3]我们可以删除3 再删除 2,再入队 [4 5],同理可以先删除4 再删除5,得到了我们的删除序列,输出yes。
第二个样例,我们的第一个删除元素是5,所有我们的入队序列为 [10 2 3 4 5],队尾删除5,[10 2 3 4],再删除10, [2 3 4],这时我们的第三个删除元素为3,而3既不在队头也不在队尾,无法删除,接着我们删除2 4,结束后我们的队列依旧有3这个元素,输出no
图片


代码如下

#include<iostream>
using namespace std;

const int N=100010;
int a[N],b[N],q[N];//插入序列 删除序列 队列
int n,m;

bool check()
{
    int hh=0,tt=-1;//队头指针 队尾指针
    for(int i=0,j=0;i<n;i++)
    {
        q[++tt]=a[i];//入队
        while(hh<=tt)//队列有元素
        {
            if(b[j]==q[hh]) j++,hh++;
            else if(b[j]==q[tt]) j++,tt--;
            else break;
        }
    }
    
    return hh>tt;//判断结束后,hh>tt 队列为空返回true
}

int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
        cin>>a[i];
    
    while(m--)
    {
        for(int i=0;i<n;i++)
            cin>>b[i];
        if(check()) cout<<"yes"<<endl;
        else cout<<"no"<<endl;
    }
    
    return 0;
}
  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值