[CF 239B][BNUOJ 26625] King's Path [模拟]

来源:互联网 发布:openwrt ip mac绑定 编辑:程序博客网 时间:2024/06/04 23:35

定义了一种语言,这种语言的语句只有两种,一种是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;}


0 0