Description
给定一个由小写字母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,你需要求出相应的距离。
InputFormat
输入的第一行是一个正整数T (T≤20 ),表示测试数据的组数。
每组输入数据的第一行是一个初始串S。第二行是一个正整数m (1≤m≤100000 ),表示总共操作的数量。接下来m行,每行表示一个操作。操作的格式如上所述。
数据保证在任何情况下,S的长度不会超过100000。
OutputFormat
对于每个QUERY,输出所求的最小距离。如果S中其它位置都不存在和它相同的字符,输出-1。
SampleInput
2
axb
3
INSERT a
QUERY 0
QUERY 1
explore
3
INSERT r
QUERY 7
QUERY 1
SampleOutput
3
-1
2
-1
#include<iostream> #define max 100000 using namespace std; char str[max]; int pos[26]; int dis[max]; //每次来一个字符, //1)这个字符如果之前没出现过,就更新下这个字符的pos位置,然后dis表示最短距离更新为maxn //2)这个字符如果出现过,pos里面出现的就是离他最近的, //然后dis[当前节点位置] = (当前节点位置 - pos这个字符最近出现的位置)。 //如果dis[pos这个字符最近出现的位置]<dis[当前节点位置],更新dis[pos这个字符最近出现的位置] void getdis(int cur) { int t = str[cur] - 'a'; if (pos[t] == -1) { pos[t] = cur; dis[cur] = max; } else { dis[cur] = cur - pos[t]; if (dis[pos[t]] > dis[cur]) dis[pos[t]] = dis[cur]; pos[t] = cur; } } int main() { int tes,len,n; char op[15]; //输入组数 scanf("%d", &tes); while (tes--) { scanf("%s", str); len = strlen(str); memset(pos, -1, sizeof(pos)); for (int i = 0; i < len; i++) getdis(i); //输入操作数 scanf("%d", &n); while (n--) { scanf("%s", op); //操作为插入 if (strcmp(op, "INSERT") == 0) { char s[2]; scanf("%s", s); str[len] = s[0]; getdis(len); len++; } //操作为查询最小距离 else { int x; scanf("%d", &x); if (dis[x] < max) printf("%d\n", dis[x]); else printf("-1\n"); } } } return 0; }