uestc oj 1831 论程序的阿卡林化

论程序的阿卡林化

本题运用双端队列+栈数据结构可以解决
首先建立一个双端队列  其实可以建立一个循环队列以节省空间,只是此题空间消耗不大,于是乎我就开了2倍空间
然后建立一个顺序栈  还有一个存放初始书籍的队列   设置一个bool变量用来显示 是否已经反转 (即双端队列是从
头存取还是尾部存取)
因为书籍的初始读入序列是自上往下的,因此在读入之后,逆序存入相应的队列 和 栈 中  
初始 flag = true  队列尾部插入  (同时要判断队列中的数量是否等于k 如果等于的话 头部元素出队进入栈中 元素仍然尾部进队)
反转 flag = false 队列头部入队  (同时判断队列中数量是否等于k      如果等于的话 尾部元素进入栈中   元素仍然头部入队)
在求取队列元素长度的时候  起初是y-x+1 未注意 队列尾部指针是空 wa了  改为 y-x  AC
在所有操作完成之后  输出元素 首先输出 队列中的元素 按照flag的true or false 输出队列中的元素(true表明队尾元素在顶端先输出false)
然后在栈中 自上而下输出元素 
在判断操作是添加还是反转的时候 用一个字符串存储输入 判断首字母确定操作  得到书名
时间复杂度O(n)级别

#include<cstdio>
#define LEN(x,y) (y-x) //此时的rear已经是向后一位逇
#define MAX 40005
struct node
{
 char s[5];
};
int n,m,k;
bool flag = true;
node y[MAX];




struct Queue
{
  int front;
  int rear;
  node date[MAX*2];
};
Queue Q;


struct Stack
{
    int top;
    node date[MAX];
};
Stack S;


Queue createQueue()
{
   Q.front =40000;
   Q.rear = 40000;
   return Q;
}


Stack createStack()
{
    S.top = 0;
    return S;
}




void add(node x)
{
    int len = LEN(Q.front,Q.rear);


    if(flag)
    {
       if(len==k)
        {  
            S.date[S.top++] = Q.date[Q.front];
            Q.front++;
        }
        Q.date[Q.rear++] = x;
    }
    else
    {
       if(len==k)
       {
            S.date[S.top++] = Q.date[Q.rear-1];
            Q.rear--;
       }
       Q.front--;
       Q.date[Q.front] = x;


    }
}


void reverse()
{


    flag = !flag;
}


bool isReverse(node &x)
{
     char tp[20]; scanf("%s", tp);
     if(tp[0]=='R') return true;
     int i;
     for(i=4;tp[i]!=')';i++)
         x.s[i-4] = tp[i];
         x.s[i-4]='\0';
     return false;
}
void deal()
{
    if(flag)
    {
          while(Q.front != Q.rear)
         {
           S.date[S.top++] = Q.date[Q.front];
           Q.front++;
         }
    }
    else
    {      while(Q.front != Q.rear)
           {
               S.date[S.top++] = Q.date[Q.rear-1];
               Q.rear--;
           }


    }
}
int main()
{
    //freopen("1.txt","r",stdin);
    while(scanf("%d%d%d",&n,&m,&k)==3)
    {
        int i;
        node x;
        createQueue();
        createStack();


        for(i =0;i<n;i++)
        scanf("%s",y[i].s);


        for(i=n-1;i>=0;i--)  //保证后来的书在上面
        add(y[i]);


        for(i=0;i<m;i++)
        {
            if(isReverse(x))
            reverse();
            else add(x);
        }
        deal();
        while(S.top>0)
        {
           printf("%s\n",S.date[--S.top].s);
        }
        printf("\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值