题目
题目描述
H a n Han Han找来兄弟伙 D o m i n i k Dominik Dominik帮他写程序,搞了一个通宵后, D o m i n i k Dominik Dominik有点恍惚就回家了,回家路上被警察盘问,警察怀疑他喝了酒,于是警察问:冒泡排序时间复杂度是多少? D o m i n i k Dominik Dominik轻松回答 n n n的平方。警察又问倒着说出英文字母表, D o m i n i k Dominik Dominik回答 z y x w v u t s r q p o n m l k j i h g f e d c b a zyxwvutsrqponmlkjihgfedcba zyxwvutsrqponmlkjihgfedcba。警察说这是你背的,没有思考,于是准备出道难题
现在想象一下,英语字母表中从“ a a a”到“ z z z”的所有字母都是顺时针方向写在一个圆圈里的。以字母“ a a a”开头,顺时针读。在每读一个字母后,警察会提出操作或询问,操作是以当前字母反向读,询问是当读到 n n n个字母后, x x x字母被读过几次?
明白规则后, D o m i n i k Dominik Dominik便开始从 a a a开始读了,请你编写一个程序,解决警察的问题。
输入
第一行,一个整数 Q Q Q,表示操作和询问总数 ( 1 ≤ Q ≤ 100000 ) (1 ≤ Q ≤ 100000) (1≤Q≤100000)
接下来 Q Q Q行,若是 U P I T n x UPIT\ n\ x UPIT n x, U P I T UPIT UPIT为克罗地亚语,表示询问,即读到第 n n n个字母时 x x x出现了几次?
若是 S M J E R n SMJER\ n SMJER n, S M J E R SMJER SMJER为克罗地亚语,表示操作,即读到第 n n n个字母时反向读。
x x x为小写字母 a z a~z a z
n n n的取值范围是 ( 1 ≤ n ≤ 1 e 9 ) (1 ≤ n ≤ 1e9) (1≤n≤1e9)
输出
一共询问行
每行一个整数,询问结果,即 x x x出现的次数
样例输入
5
UPIT 1 b
UPIT 3 b
SMJER 4
UPIT 7 a
UPIT 10 z
样例输出
0
1
2
1
题解
先吐槽一波,考试时老师一直说这个题很难,搞得我想到模拟的时候一阵慌不敢打
但这个题一看就是模拟啊。。。
我们只需要用一个变量记录当前读字母的方向,由于数据保证 n n n递增,我们就直接循环两次询问之间所经过的字母,将每一个字母出现的次数加一即可,这有什么难的
最后要考虑一个优化,不然 O ( N Q ) O(NQ) O(NQ)的复杂度肯定超时,如果两次 n n n相差很大,我们可以直接算出读了多少圈,也就是每个字母一定会被读到的次数,再将剩余的处理就可以了
代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int q, n, start, step;
int cnt[30];
char s;
char a[10];
bool dir; //0顺1逆
int main() {
scanf("%d", &q);
step = 0;
start = 0;
for(int i = 1; i <= q; i ++) {
scanf("\n");
scanf("%s", a);
scanf("%d", &n);
int p = n - step;
for(int i = 1; i <= 26; i ++)
cnt[i] += p / 26;
p %= 26;
if(dir == 0) {
for(int i = 1; i <= p; i ++) {
if(start + i <= 26) cnt[start + i] ++;
else cnt[(start + i) % 26] ++;
}
start += p;
if(start > 26) start %= 26;
}
else {
for(int i = 1; i <= p; i ++) {
if(start - i >= 1) cnt[start - i] ++;
else cnt[start - i + 26] ++;
}
start -= p;
if(start < 1) start += 26;
}
if(a[0] == 'U') {
s = getchar();
s = getchar();
printf("%d\n", cnt[s - 'a' + 1]);
}
else {
if(dir == 0) dir = 1;
else dir = 0;
}
step = n;
}
return 0;
}