AOJ1145 The Genome Database of All Space Life
「$ length(k,l,r) = $ 文字列の区間 $[l,r)$ を展開したときの $k$ 番目の文字」とおく. あとは頑張る.繰り返すアルファベットが $1$ 文字の場合でも強制的に括弧を付けるようにすると楽になった.
#include <cstring>
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <cassert>
using namespace std;
char s[5000];
int length(int const k, int const l, int const r){
int cur = 0, res = 0, p = l;
while(s[p] && p < r){
if(isalpha(s[p])){
while(isalpha(s[p])){
if(cur == k) throw s[p];
res++;
p++;
cur++;
}
} else if(isdigit(s[p])){
int mul = 0;
while(isdigit(s[p])){
mul = mul * 10 + s[p] - '0';
p++;
}
int d = 0, i = p++;
while(1){
if(s[i] == '(') d++;
else if(s[i] == ')') d--;
if(d == 0) break;
i++;
}
int memo = -1;
for(int j = 0; j < mul; j++){
if(memo != -1 && cur + memo < k){
res += memo;
cur += memo;
} else {
int x = length(k - cur, p, i);
res += x;
cur += x;
memo = x;
}
}
p = i + 1;
}
}
return res;
}
int main(){
static char t[5000];
int k;
while(scanf("%s%d",t,&k), t[0] != '0'){
int tlen = strlen(t);
int len = 0;
for(int i = 0; i < tlen; i++){
if(i > 0 && isdigit(t[i - 1]) && isalpha(t[i])){
s[len++] = '(';
s[len++] = t[i];
s[len++] = ')';
} else {
s[len++] = t[i];
}
}
s[len] = 0;
try{
length(k, 0, len);
putchar('0');putchar('\n');
} catch (char e) {
putchar(e);putchar('\n');
}
}
}