题目描述
输入
第一行为两个数n与m,表示操作数与a的长度,1 ≤ n, m ≤ 106。
第二行为m个数,表示序列a,ai<=106。
后面共有n行,每行有一个整数(0/1/-1),表示操作类型。
输出
最终的序列w。若序列为空,输出Poor stack!
输入样例
样例1:
输入
10 3
1 3 6
-1
1
1
0
0
-1
0
1
-1
1
样例2:
输入
2 1
1
1
-1
输出样例
样例1:
输出
011
样例2:
输出
Poor stack!
思路:
用空间换时间
用两个数组模拟链表的操作,数组ch存序列数据,数组Next存下一个(数组ch)结点的下标。
Next[0]为头结点,头结点不存数据,若Next[0]=k,则序列ch中第一个元素的下标为k,若ch[Next[0]]=k表示此时序列的第一个数字为k,k=0或1
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAX=1e6+10;
char ch[2*MAX];
int Next[2*MAX];
int num[MAX];
int n,m;
int top=0;//从1开始
void init(){
cin>>n>>m;
memset(Next,0,sizeof(Next));
for(int i=0;i<m;i++)
scanf("%d",&num[i]);
for(int i=m-1;i>=1;i--)
num[i]-=num[i-1];
}
void solve(){
int temp;
int choice;
int end=0;
//Next[0]为头结点
while(n--){
scanf("%d",&choice);
if(choice==0){
ch[++top]='0';
Next[end]=top;
end=top;
}else if(choice==1){
ch[++top]='1';
Next[end]=top;
end=top;
}else {
if (Next[0] == 0)
continue;
temp = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < num[i] - 1; j++) {
if (Next[temp] == 0)
break;
temp = Next[temp];
}
if(Next[temp]==0){
break;
}
Next[temp] = Next[Next[temp]];
}
if(Next[temp]==0)
end=temp;
}
}
if(Next[0]==0){
cout<<"Poor stack!";
}else{
int first=0;
while(Next[first]!=0){
cout<<ch[Next[first]];
first=Next[first];
}
}
}
int main() {
init();
solve();
return 0;
}