sgu 271


用双向队列维护最上面的 k 本书,翻转什么的就很傻逼了。

时间复杂度:O(n+m)


另外, STL 中有双向队列,真是太感动了。。。


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <vector>
#include <iostream>
#include <algorithm>

const int Base = 29, size = 40005;

int n, m, k, flag;
std::vector<int> orgin;
std::deque<int> line;
std::vector<int> ans;

int trans(char str[])
{
    int sl = strlen(str), ret = 0, hp = 1;
    for(int i = 0; i < sl; i++)
        ret += (str[i]-'A'+1) * hp, hp *= Base;
    return ret;
}
void prt(int num)
{
    while(num) putchar(num%Base +'A'-1), num /= Base;
}
int caught(char u[])
{
    int ul = strlen(u), ret = 0, hp = 1;
    for(int i = 4; i < ul - 1; i++)
        ret += (u[i]-'A'+1) * hp, hp *= Base;
    return ret; 
}
int pop()
{
    int ret;
    if(flag)ret = line.back(), line.pop_back(); 
    else ret = line.front(), line.pop_front();
    return ret;
}
void push(int s)
{
    if(flag) line.push_front(s);
    else line.push_back(s);

}
void insert(int sf)
{
    push(sf);

    if(line.size() > k)
        ans.push_back(pop());
}

int main()
{
    char op[Base];

#ifndef ONLINE_JUDGE
    freopen("sgu271.in","r",stdin);
    freopen("sgu271.out","w",stdout);
#endif

    std::cin >> n >> m >> k;
    for(int i = 0; i < n; i++)
        scanf("%s",op), orgin.push_back(trans(op));
    for(int i = n - 1; i >= 0; i--) insert(orgin[i]);

    while(m--)
    {
        scanf("%s",op);
        switch(op[0])
        {
            case 'A': insert(caught(op)); break;
            case 'R': flag ^= 1; break;
        }
    }

    while(!line.empty()) ans.push_back(pop());
    for(int i = ans.size() - 1; i >= 0; i--)
        prt(ans[i]), putchar('\n');


#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
#endif
    return 0;
}

以下是无 STL 的版本。。。


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

const int Base = 29, size = 40005;

int n, m, k;
int orgin[size];
int line[size], f, r, flag;
int ans[size], al;

int trans(char str[])
{
    int sl = strlen(str), ret = 0, hp = 1;
    for(int i = 0; i < sl; i++)
        ret += (str[i]-'A'+1) * hp, hp *= Base;
    return ret;
}
void prt(int num)
{
    while(num) putchar(num%Base +'A'-1), num /= Base;
}
int caught(char u[])
{
    int ul = strlen(u), ret = 0, hp = 1;
    for(int i = 4; i < ul - 1; i++)
        ret += (u[i]-'A'+1) * hp, hp *= Base;
    return ret; 
}
int pop()
{
    int ret;
    if(flag) r = (r-1+size)%size, ret = line[r]; 
    else ret = line[f], f = (f+1)%size;
    return ret;
}
void push(int s)
{
    if(flag) f = (f-1+size)%size, line[f] = s;
    else line[r] = s, r = (r+1)%size;   
}
void insert(int sf)
{
    push(sf);

    if((r-f+size)%size > k)
        ans[++al] = pop();
}

int main()
{
    char op[Base];

#ifndef ONLINE_JUDGE
    freopen("sgu271.in","r",stdin);
    freopen("sgu271.out","w",stdout);
#endif

    std::cin >> n >> m >> k;
    for(int i = 1; i <= n; i++)
        scanf("%s",op), orgin[i] = trans(op);
    for(int i = n; i >= 1; i--)
        insert(orgin[i]);
    for(int i = 1; i <= m; i++)
    {
        scanf("%s",op);
        switch(op[0])
        {
            case 'A': insert(caught(op));break;
            case 'R': flag ^= 1;break;
        }
    }
    while(f != r) ans[++al] = pop();
    for(int i = al; i >= 1; i--)
        prt(ans[i]), putchar('\n');


#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
#endif
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值