北邮OJ-94. 最小距离查询

题目描述 
给定一个由小写字母a到z组成的字符串S,其中第i个字符为S[i](下标从0开始)。你需要完成下面两个操作: 
INSERT c 
其中c是一个待输入的字符。你需要在字符串的末尾添加这个字符。保证输入的字符同样是a到z之间的一个小写字母。 
QUERY x 
其中x是一个输入的整数下标。对于这个询问,你需要回答在S当中和S[x]相等且与x最近的距离。输入保证x在当前字符串中合法。 
例如S = “abcaba”,如果我们操作: 
INSERT a 
则在S的末端加一个字符a,S变成”abcabaa”。 
接下来操作 
QUERY 0 
由于S[0] = a,在S中出现的离他最近的a在下标为3的位置上,距离为3 - 0 = 3。因此应当输出3。 
接下来,如果 
QUERY 4 
S[4] = b,S中离它最近的b出现在下标为1处,距离为4 - 1 = 3。同样应当输出3。 
给定初始字符串S和若干操作,对于每个QUERY,你需要求出相应的距离。

HINT 由于输入数据较大,C/C++中推荐使用scanf进行读入以获得更快的读入速度。同时请注意算法复杂度。

输入格式 
输入的第一行是一个正整数T(T≤20),表示测试数据的组数。 
每组输入数据的第一行是一个初始串S。第二行是一个正整数m(1≤m≤100000),表示总共操作的数量。接下来m行,每行表示一个操作。操作的格式如上所述。 
数据保证在任何情况下,S的长度不会超过100000。

输出格式 
对于每个QUERY,输出所求的最小距离。如果S中其它位置都不存在和它相同的字符,输出-1。

输入样例 

axb 

INSERT a 
QUERY 0 
QUERY 1 
explore 

INSERT r 
QUERY 7 
QUERY 1 
输出样例 

-1 

-1

以下是代码:很简单,很容易理解。如果有什么问题请留言。

#include <stdio.h>
#include <string.h>
#define SIZE 100001
#define min(x,y) x<y ? x:y 
int abs(int x){
	return x>0 ? x:-x;
}
int main(){
	int t,n;
	char buf[SIZE];
	memset(buf,0,sizeof(buf));
	scanf("%d",&t);
	scanf("%s",buf);
	while(t--){
		scanf("%d",&n);
		while(n--){
			char buf1[10];
			scanf("%s",buf1);
			if(strcmp(buf1,"INSERT")==0){
				char b[2];
				scanf("%s",b);
				strcat(buf,b);
			}else if(strcmp(buf1,"QUERY")==0){
				int a;
				scanf("%d",&a);
				int ans=0,j=0;
				for(int i=0;i<strlen(buf);i++){
					if(buf[a]=='\0'){
						ans=abs(a-strlen(buf));
					}else if(buf[i]==buf[a] && i!=a){
						j++;
						if(j==1){
							ans=abs(i-a);//只有一次出现
						}else{
							ans=min(ans,abs(i-a));//多次出现
						}
					}
				}
				printf("%d\n",ans==0 ? -1:ans); 
			}
		}
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值