hdu 1981

地址: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 }
posted @ 2012-04-27 09:05  Seraph2012  阅读(266)  评论(0编辑  收藏  举报