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

9 篇文章 0 订阅
4 篇文章 0 订阅

定义了一种语言,这种语言的语句只有两种,一种是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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值