地址:http://acm.hdu.edu.cn/showproblem.php?pid=1981
题意:给长度为n的小写字母字符串,有3种操作:
"Q A":输出当前字符串的第A个字符;
"S A B":把第A个到第B个字符都加1。a变成b,b变成c,z变成a。。。
"R A B":把从A到B的字符串逆转。
输出就是Q操作的时候的输出。
mark:这题真是tricky。一看8w个字符,先知道直接搞是肯定不行的。后来想了一下也没想到好办法。查了一下,原来可以记录下每次的操作,然后查询的时候根据位置往前循环,因为查找次数少,因而效率比较高。一开始wawawa。。。后来才发现是把int数组开成了char。。。各种2啊。。。
代码:
1 # include <stdio.h> 2 3 4 char str[80010] ; 5 char com[3010] ; 6 int a[3010], b[3010] ; 7 8 9 int gao(int idx) 10 { 11 int i, cc = 0, pos = a[idx] ; 12 for (i = idx-1 ; i >= 0 ; i--) 13 { 14 if (com[i] == 'Q') continue ; 15 else if (com[i] == 'S' && pos >= a[i] && pos <= b[i]) 16 cc++ ; 17 else if (com[i] == 'R' && pos >= a[i] && pos <= b[i]) 18 pos = a[i]+b[i]-pos ; 19 } 20 return (str[pos]-'a'+cc)%26 + 'a' ; 21 } 22 23 24 int main () 25 { 26 int T, n, c, i ; 27 char op[5] ; 28 29 // freopen ("in.txt", "r", stdin) ; 30 // freopen ("out.txt", "w", stdout) ; 31 32 33 scanf ("%d", &T) ; 34 while (T--) 35 { 36 scanf ("%d%d%s", &n, &c, str+1) ; 37 for (i = 0 ; i < c ; i++) 38 { 39 scanf ("%s %d", op, &a[i]) ; 40 com[i] = op[0] ; 41 if (com[i] != 'Q') scanf ("%d", &b[i]) ; 42 else printf ("%c\n", gao(i)) ; 43 } 44 } 45 return 0 ; 46 }