atcoder-C

(i + cnt) % m = x - 1,i表示一开始的下标,x表示要求的第几个元素,m表示字符串大小,所以我们只需要求出i值即可。然后因为i < m,cnt < m,所以i+cnt < 2m,所以i = (x + m - 1 - cnt) % m

优雅 ~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

int n, q;
string s;

int main() {
cin >> n >> q;
cin >> s;

int cnt = 0;
int m = s.size();
while(q --) {
int k, x;
scanf("%d%d", &k, &x);
if(k == 1) {
cnt += x;
cnt %= m;
}
else
printf("%c\n", s[(x + m - 1 - cnt) % m]);
}

return 0;
}

我相信每个人在遇到一个新的困难、新的挫折、新的挑战所具备的能力是一样的,只是大部分人都想活在思想的舒适区,这样一来就有了区分度。

虫食算

dfs剪枝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 30;

char e[3][N];
int n;
bool st[N];
int q[N], path[N];

bool check() {
for(int i = n - 1, t = 0; ~i; i --) {
int a = e[0][i] - 'A', b = e[1][i] - 'A', c = e[2][i] - 'A';

if(path[a] != -1 && path[b] != -1 && path[c] != -1) {
a = path[a], b = path[b], c = path[c];
if(t != -1) {
if((a + b + t) % n != c) return false;
if(!i && (a + b + t) >= n) return false;
t = (a + b + t) / n;
}
else { //如果进位不确定,那么进位不是0就是1
if((a + b) % n != c && (a + b + 1) % n != c) return false;
if(!i && a + b >= n) return false;
}
}
else t = -1;
}
return true;
}

bool dfs(int u) {
if(u == n) return true;

for(int i = 0; i < n; i ++) {
if(!st[i]) {
st[i] = true;
path[q[u]] = i;
if(check() && dfs(u + 1))
return true;
st[i] = false;
path[q[u]] = -1;
}
}

return false;
}

int main() {
cin >> n;
for(int i = 0; i < 3; i ++) cin >> e[i];

for(int i = n - 1, k = 0; ~i; i --)
for(int j = 0; j < 3; j ++) {
int t = e[j][i] - 'A';
if(!st[t]) {
st[t] = true;
q[k ++] = t;
}
}

memset(st, 0, sizeof(st));
memset(path, -1, sizeof(path));

dfs(0);

for(int i = 0; i < n; i ++)
cout << path[i] << ' ';

return 0;
}