Codeforces Round 930 Div. 2
A. Shuffle Party
A. Shuffle Party
time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output
You are given an array
a
1
,
a
2
,
…
,
a
n
a_1, a_2, \ldots, a_n
a1,a2,…,an. Initially,
a
i
=
i
a_i=i
ai=i for each
1
≤
i
≤
n
1 \le i \le n
1≤i≤n.
The operation
swap
(
k
)
\texttt{swap}(k)
swap(k) for an integer
k
≥
2
k \ge 2
k≥2 is defined as follows:
- Let
d
d
d be the largest divisor
†
^\dagger
† of
k
k
k which is not equal to
k
k
k itself. Then swap the elements
a
d
a_d
ad and
a
k
a_k
ak.
Suppose you perform swap ( i ) \texttt{swap}(i) swap(i) for each i = 2 , 3 , … , n i=2,3,\ldots, n i=2,3,…,n in this exact order. Find the position of 1 1 1 in the resulting array. In other words, find such j j j that a j = 1 a_j = 1 aj=1 after performing these operations.
† ^\dagger † An integer x x x is a divisor of y y y if there exists an integer z z z such that y = x ⋅ z y = x \cdot z y=x⋅z.
Input
Each test contains multiple test cases. The first line contains the number of test cases
t
t
t (
1
≤
t
≤
1
0
4
1 \le t \le 10^4
1≤t≤104). The description of the test cases follows.
The only line of each test case contains one integer
n
n
n (
1
≤
n
≤
1
0
9
1 \le n \le 10^9
1≤n≤109) — the length of the array
a
a
a.
Output
For each test case, output the position of 1 1 1 in the resulting array.
Input
4
1
4
5
120240229
Output
1
4
4
67108864
Note
In the first test case, the array is [ 1 ] [1] [1] and there are no operations performed.
In the second test case, a a a changes as follows:
- Initially, a a a is [ 1 , 2 , 3 , 4 ] [1,2,3,4] [1,2,3,4].
- After performing swap ( 2 ) \texttt{swap}(2) swap(2), a a a changes to [ 2 ‾ , 1 ‾ , 3 , 4 ] [\underline{2},\underline{1},3,4] [2,1,3,4] (the elements being swapped are underlined).
- After performing swap ( 3 ) \texttt{swap}(3) swap(3), a a a changes to [ 3 ‾ , 1 , 2 ‾ , 4 ] [\underline{3},1,\underline{2},4] [3,1,2,4].
- After performing swap ( 4 ) \texttt{swap}(4) swap(4), a a a changes to [ 3 , 4 ‾ , 2 , 1 ‾ ] [3,\underline{4},2,\underline{1}] [3,4,2,1].
Finally, the element 1 1 1 lies on index 4 4 4 (that is, a 4 = 1 a_4 = 1 a4=1). Thus, the answer is 4 4 4.
1、模拟过程
例如,数组的长度是 5 5 5,由题可知, d d d是 k k k的最大除数,但是 d d d不等于 k k k,则如果 k % d = 0 k\%d=0 k%d=0,那么就将下标为 d d d和 k k k的元素进行交换,模拟过程如下:
i i i | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
a [ i ] a[i] a[i] | 1 | 2 | 3 | 4 | 5 |
⇓ \Darr ⇓
i i i | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
a [ i ] a[i] a[i] | 2 | 1 | 3 | 4 | 5 |
⇓ \Darr ⇓
i i i | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
a [ i ] a[i] a[i] | 3 | 1 | 2 | 4 | 5 |
⇓ \Darr ⇓
i i i | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
a [ i ] a[i] a[i] | 3 | 4 | 2 | 1 | 5 |
⇓ \Darr ⇓
i i i | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
a [ i ] a[i] a[i] | 5 | 4 | 2 | 1 | 3 |
2、代码
#include<iostream>
using namespace std;
const int N = 1e4 + 10;
int t, n;
int main() {
scanf("%d", &t);
while (t--) {
int p = 1;
scanf("%d", &n);
while (2 * p <= n) {
p <<= 1;
}
printf("%d\n", p);
}
return 0;
}
B. Binary Path
B. Binary Path
time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output
You are given a 2 × n 2 \times n 2×n grid filled with zeros and ones. Let the number at the intersection of the i i i-th row and the j j j-th column be a i j a_{ij} aij.
There is a grasshopper at the top-left cell ( 1 , 1 ) (1, 1) (1,1) that can only jump one cell right or downwards. It wants to reach the bottom-right cell ( 2 , n ) (2, n) (2,n). Consider the binary string of length n + 1 n+1 n+1 consisting of numbers written in cells of the path without changing their order.
Your goal is to:
- Find the lexicographically smallest † ^\dagger † string you can attain by choosing any available path;
- Find the number of paths that yield this lexicographically smallest string.
† ^\dagger † If two strings s s s and t t t have the same length, then s s s is lexicographically smaller than t t t if and only if in the first position where s s s and t t t differ, the string s s s has a smaller element than the corresponding element in t t t.
Input
Each test contains multiple test cases. The first line contains the number of test cases t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1≤t≤104). The description of the test cases follows.
The first line of each test case contains a single integer n n n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 2 \le n \le 2 \cdot 10^5 2≤n≤2⋅105).
The second line of each test case contains a binary string a 11 a 12 … a 1 n a_{11} a_{12} \ldots a_{1n} a11a12…a1n ( a 1 i a_{1i} a1i is either 0 0 0 or 1 1 1).
The third line of each test case contains a binary string a 21 a 22 … a 2 n a_{21} a_{22} \ldots a_{2n} a21a22…a2n ( a 2 i a_{2i} a2i is either 0 0 0 or 1 1 1).
It is guaranteed that the sum of n n n over all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.
Output
For each test case, output two lines:
- The lexicographically smallest string you can attain by choosing any available path;
- The number of paths that yield this string.
Input
3
2
00
00
4
1101
1100
8
00100111
11101101
Output
000
2
11000
1
001001101
4
Note
In the first test case, the lexicographically smallest string is 000 \mathtt{000} 000. There are two paths that yield this string:
In the second test case, the lexicographically smallest string is 11000 \mathtt{11000} 11000. There is only one path that yields this string:
1、过程模拟
由题可知,蚂蚱只能向右或者是向下移动,并且使得二进制数的值是最小的路径,路径条数不止一条,但二进制数值是一样的。
我们可以先从第一行的最后一列和第二行的倒数第二列进行比较,设
m
a
x
_
d
o
w
n
=
n
max\_down=n
max_down=n,
m
i
n
_
d
o
w
n
=
1
min\_down=1
min_down=1,如果第一行的最后一列是
1
1
1,第二行的倒数第二列是
0
0
0,则将第一行原本的长度减一,即
m
a
x
_
d
o
w
n
=
n
−
1
max\_down=n-1
max_down=n−1。
再从第二行的第一列和第一行的第二列进行比较,设
m
a
x
_
d
o
w
n
=
n
max\_down=n
max_down=n,
m
i
n
_
d
o
w
n
=
1
min\_down=1
min_down=1,如果第二行的第一列是
1
1
1,第一行的第二列是
0
0
0,则
m
i
n
_
d
o
w
n
=
1
+
1
min\_down=1+1
min_down=1+1,根据以上步骤以此类推。
2、代码
#include<iostream>
#include<algorithm>
using namespace std;
#define orz 0
const int N = 2e5 + 10;
int t, n;
char a[4][N];
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 1; i <= 2; i++) {
scanf("\n");
for (int j = 1; j <= n; j++) {
scanf("%c", &a[i][j]);
}
}
int max_down = n, min_down = 1;
for (int i = n; i >= 2; i--) {
if (a[1][i] == '1' && a[2][i - 1] == '0') {
max_down = i - 1;
}
}
for (int i = 1; i < max_down; i++) {
if (a[1][i + 1] == '0' && a[2][i] == '1') {
min_down = i + 1;
}
}
for (int i = 1; i <= max_down; i++) {
printf("%c", a[1][i]);
}
for (int i = max_down; i <= n; i++) {
printf("%c", a[2][i]);
}
puts("");
printf("%d\n", max_down - min_down + 1);
}
return orz;
}