定义了一种语言,这种语言的语句只有两种,一种是0~9之间的一个数字,另一种是'<'或者'>'符号。
解释器由两个指针构成,一个指针指着当前语句(语句指针),一个指针表示下一条语句的方向(方向指针)。
解释某个语句时,若当前语句为一个数字,则打印该数字,语句指针向方向指针移动一位,若之前的数字大于零,令该数字减一,否则删除该数字。
若当前语句为一个符号,则根据该符号改变方向指针的方向,语句指针向方向指针移动一位。若之前的语句也是改变方向的语句,则删除之前的那个符号。
若语句指针离开程序段,则程序结束。
现在给你一段程序,然后再给你若干次询问,每次询问有l,r两个整数,求若以原程序的第l句到第r句(闭区间)为一个独立的程序,会输出的每个数字的次数。
直接模拟即可,用双向链表维护以方便的删除一个语句
数据范围:程序段长度不超过100,询问次数不超过100次
时间复杂度分析:每个数字语句被执行的次数显然不超过10次,每个指针语句被执行的语句均摊不超过七次,在不会删除符号语句的前提下,要向第二次执行某语句,则该语句和相邻的符号语句之间的数字语句都已经被执行过两次了,第六次执行该语句时,该语句与相邻的符号语句之间一定不再存在数字语句,第七次执行该语句时,上一个执行的一定是一个应该被删除的符号语句。
#include <cstdio>
#include <cstring>
int l[110];
int r[110];
char data[110];
int ans[10];
void erase(int i) {
if (l[i]!=-1) r[l[i]]=r[i];
if (r[i]!=-1) l[r[i]]=l[i];
}
void gao() {
bool right=true;
int i=0,lastD=-1;
while (i!=-1) {
if (data[i]>='0'&&data[i]<='9') {
ans[data[i]-'0']++;
data[i]--;
if (data[i]<'0') erase(i);
lastD=-1;
} else {
if (data[i]=='>') right=true;
else right=false;
if (lastD!=-1) {
erase(lastD);
}
lastD=i;
}
if (right) i=r[i];
else i=l[i];
}
}
int main() {
int n,q,ll,rr,nn,i,j;
char s[110];
scanf("%d%d",&n,&q);
scanf("%s",s);
while (q--) {
scanf("%d%d",&ll,&rr);
ll--;rr--;
nn=rr-ll+1;
for (i=0;i<nn;i++) {
l[i]=i-1;
r[i]=i+1;
data[i]=s[i+ll];
}
l[0]=r[nn-1]=-1;
memset(ans,0,sizeof(ans));
//printf("%s\n",data);
gao();
printf("%d",ans[0]);
for (i=1;i<10;i++) printf(" %d",ans[i]);
printf("\n");
}
return 0;
}