北邮机试 | bupt oj | 94. 最小距离查询

版权声明:欢迎转载 https://blog.csdn.net/stone_fall/article/details/88422047

时间限制 1000 ms 内存限制 65536 KB

题目描述

给定一个由小写字母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。

输入样例

2
axb
3
INSERT a
QUERY 0
QUERY 1
explore
3
INSERT r
QUERY 7
QUERY 1

输出样例

3
-1
2
-1

AC代码

//r
#include<bits/stdc++.h>
#define MAXN 100010
#define INF 1e9
using namespace std;
char s[MAXN];
int cnt[27], pre[27];
int dp[MAXN][2];
int c_query(int index){
    int ans = min(dp[index][0],dp[index][1]);
    if(ans !=INF)
        return ans;
    else return -1;
}
void c_insert(char character,int &len){
    s[len] = character;
    int tmp=character -'a';
    cnt[tmp]++;
    if(cnt[tmp]>=2)
    {
        dp[len][0]=dp[pre[tmp]][1]=len-pre[tmp];
    }
    pre[tmp]=len++;
}
void initDis(char s[],int len){
    int tmp;
    for(int i=0;i<len;i++){
        tmp = s[i]-'a';
        cnt[tmp]++;
        if(cnt[tmp]>=2){
            dp[i][0]=dp[pre[tmp]][1]=i-pre[tmp];
        }
        pre[tmp]=i;
    }
    //for(int i=0;i<len;i++){
    //	printf("%d %d\n",dp[i][0],dp[i][1]);
	//} 
}
void init(){
    for(int i=0;i<MAXN;i++)
        dp[i][0]=dp[i][1]=INF;
    for(int i=0;i<27;i++){
        cnt[i]=pre[i]=0;
    }
}
int main()
{
    int t,m,index;
    char command[10],character[10];
    scanf("%d",&t);
    while(t--){
        scanf("%s",s);
        int len = strlen(s);
        init();
        initDis(s,len);
        scanf("%d",&m);
        while(m--){
            scanf("%s",command);
            if(command[0] == 'Q'){
            	scanf("%d",&index);
                int ans = c_query(index);
                printf("%d\n",ans);
            }
            else if(command[0] == 'I'){
            	scanf("%s",character);
                c_insert(character[0],len);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/stone_fall/article/details/88422047
今日推荐