woj658 华师2017校赛A题 队列

Description

有一个空的初始队列,支持三种操作:

  1. 向队首加入一个数。
  2. 将队列复制一次,放到队首。假设队列中原有 a_1,a_2,\ldots,a_na1,a2,,an, 变换后为 a_1,a_2,\ldots ,a_n, a_1,a_2,\ldots ,a_na1,a2,,an,a1,a2,,an
  3. 将队列队首元素弹出。

现要你写一个程序,实现这样的队列。

Input

输入数据第一行为测试用例数目 TT。之后为 TT 组测试用例。

每组测试用例的第一行为操作数 QQ。之后的一行有 QQ 个数,表示对队列的顺序操作。

某个数字如果是正整数,则表示向队列头加入这个数(操作 1);如果是 0,表示对队列进行操 作 2;如果是-1,表示弹出队首元素(操作 3)。

当队列为空的时候,可能会要求你进行第三种操作,此时不用对队列做任何处理。

数据保证:

  1. TT 不超过 100
  2. QQ 不超过 100000
  3. 表示操作的数不超过 10^9109
  4. 至多有 5 组测试用例的 QQ 超过 1000

Output

每个操作(除了对空队列进行操作 3)应该得到一个结果。操作 1 和 2 的结果是操作后队列的长 度;操作 3 的结果是当前弹出的元素。

因为输出的太多,不要求你将所有的结果输出。而是要求你在每组测试数据的第一个操作前创建 一个为 0 的变量 XX,每得到一个新的操作结果,将 XX 置为 2333 倍的 XX 与当前输出的和取膜 10^9 +7109+7。 即:

X = (X * 2333 + current_result) % MOD

对于第 ii 个测试用例,首先输出CASE #i:之后输出一个空格,然后是结果。

Sample Input

1
5
9 10 0 -1 -1

Sample Output

CASE #1: 458773740

Hint

五次操作的结果分别是:1,2,4,10,9

Source

2017 年"计蒜客杯" 华中师范大学第十五届程序设计竞赛


题解:思路很容易想到,就是用队列的前面一部分去模拟整个队列(因为当队列中元素很多时,就算不停地删除也只与前面的有关,插入同理,复制则不变)

因为都是在头部操作,所以使用deque

有几个陷阱:

1.当判断队列为空时不能用length变量因为有可能取mod之后为0;要用.empty()

2.length要设置为long long以免溢出

3.当对deque进行插入删除操作时不能使用迭代器。


#include<bits/stdc++.h>
using namespace std;
deque<int> dq;
const long long Mod=1000000000+7;
const int maxn=100000+10;
long long length;//this length is mod by Mod
int a[maxn],n;
int backup[maxn<<1];
deque<int>::iterator it_begin,it_end,it;
long long ans;
int main(void)
{
    int T;
    cin>>T;
    for(int ii=1;ii<=T;ii++)
    {
        length=ans=0;
        dq.clear();
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            if((a[i]==-1)&&dq.empty())//empty and pop,no result
                continue;
            if(a[i]>0)
            {
                dq.push_front(a[i]);
                length=(length+1)%Mod;
                ans=(ans*2333+length)%Mod;
            }
            if(a[i]==-1)
            {
                ans=(ans*2333+dq.front())%Mod;
                dq.pop_front();
                length=(length-1+Mod)%Mod;
            }
            if(a[i]==0)
            {
                length=length*2;
                length%=Mod;
                ans=(ans*2333+length)%Mod;
                if(dq.size()>200000)
                    continue;
                else
                {
                    int num=0;
                    for(auto it:dq)
                        backup[num++]=it;
                    for(int i=0;i<num;i++)
                        dq.push_back(backup[i]);
                }

            }
        }
        printf("CASE #%d: ",ii);
        cout<<ans<<endl;
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值