Harbour.Space Scholarship Contest 2023-2024 (Div. 1 + Div. 2)


A. Increasing and Decreasing

time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
outputL: standard output

You are given three integers x x x, y y y, and n n n.

Your task is to construct an array a a a consisting of n n n integers which satisfies the following conditions:

  1. a 1 = x a_1=x a1=x, a n = y a_n=y an=y;
  2. a a a is strictly increasing (i.e. a 1 < a 2 < … < a n a_1 < a_2 < \ldots < a_n a1<a2<<an);
  3. if we denote b i = a i + 1 − a i b_i=a_{i+1}-a_{i} bi=ai+1ai for 1 ≤ i ≤ n − 1 1 \leq i \leq n-1 1in1, then b b b is strictly decreasing (i.e. b 1 > b 2 > … > b n − 1 b_1 > b_2 > \ldots > b_{n-1} b1>b2>>bn1).

If there is no such array a a a, print a single integer − 1 -1 1.

Input

Each test contains multiple test cases. The first line contains the number of test cases t t t ( 1 ≤ t ≤ 1000 1 \le t \le 1000 1t1000). The description of the test cases follows.

The only line of each test case contains three integers x x x, y y y, n n n ( 1 ≤ x < y ≤ 1000 , 3 ≤ n ≤ 1000 1 \le x < y \le 1000,3 \le n \le 1000 1x<y1000,3n1000).

Output

For each test case, output n n n integers a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a1,a2,,an. If there are multiple solutions, print any of them.

If there is no solution, print a single integer − 1 -1 1.

Example
input

3
1 4 3
1 3 3
100 200 4

output

1 3 4
-1
100 150 180 200

Note

In the first test case, a = [ 1 , 3 , 4 ] a=[1,3,4] a=[1,3,4], which is strictly increasing. Next, b 1 = a 2 − a 1 = 3 − 1 = 2 b_1=a_2-a_1=3-1=2 b1=a2a1=31=2, b 2 = a 3 − a 2 = 4 − 3 = 1 b_2=a_3-a_2=4-3=1 b2=a3a2=43=1, thus b = [ 2 , 1 ] b=[2,1] b=[2,1], which is strictly decreasing.

In the second test case, there is no array a a a that satisfies all the conditions above.

Tutorial
利用贪心,对于所有的 i ( 1 < i < n ) i(1 < i < n) i(1<i<n),都有 a i = a i + 1 − ( n − i ) a_i = a_{i + 1} - (n - i) ai=ai+1(ni) ,则需要满足 a 2 − a 1 ≥ n − 1 a_2 - a_1 \ge n - 1 a2a1n1 才能有解

Solution

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long

void solve() {
    int x, y, n, diff = 1;
    cin >> x >> y >> n;
    vector<int> ans;
    ans.emplace_back(y);
    for (int i = 1; i < n; ++i) {
        ans.emplace_back(ans.back() - diff);
        diff++;
    }
    ranges::reverse(ans);
    if (ans[0] < x) {
        cout << -1 << endl;
        return;
    }
    cout << x << " \n"[n == 1];
    for (int i = 1; i < n; ++i) {
        cout << ans[i] << " \n"[i == n - 1];
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cout << fixed << setprecision(15);
    int test; cin >> test; while (test--)
    solve();
    return 0;
}

B. Swap and Reverse

time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
outputL: standard output

You are given a string s s s of length n n n consisting of lowercase English letters, and an integer k k k. In one step you can perform any one of the two operations below:

  • Pick an index i i i ( 1 ≤ i ≤ n − 2 1 \le i \le n - 2 1in2) and swap s i s_{i} si and s i + 2 s_{i+2} si+2.
  • Pick an index i i i ( 1 ≤ i ≤ n − k + 1 1 \le i \le n-k+1 1ink+1) and reverse the order of letters formed by the range [ i , i + k − 1 ] [i,i+k-1] [i,i+k1] of the string. Formally, if the string currently is equal to s 1 … s i − 1 s i s i + 1 … s i + k − 2 s i + k − 1 s i + k … s n − 1 s n s_1\ldots s_{i-1}s_is_{i+1}\ldots s_{i+k-2}s_{i+k-1}s_{i+k}\ldots s_{n-1}s_n s1si1sisi+1si+k2si+k1si+ksn1sn, change it to s 1 … s i − 1 s i + k − 1 s i + k − 2 … s i + 1 s i s i + k … s n − 1 s n s_1\ldots s_{i-1}s_{i+k-1}s_{i+k-2}\ldots s_{i+1}s_is_{i+k}\ldots s_{n-1}s_n s1si1si+k1si+k2si+1sisi+ksn1sn.

You can make as many steps as you want (possibly, zero). Your task is to find the lexicographically smallest string you can obtain after some number of steps.

A string a a a is lexicographically smaller than a string b b b of the same length if and only if the following holds:

  • in the first position where a a a and b b b differ, the string a a a has a letter that appears earlier in the alphabet than the corresponding letter in b b b.

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 1t104). The description of the test cases follows.

The first line of each test case contains two integers n n n and k k k ( 1 ≤ k < n ≤ 1 0 5 1 \le k < n \le 10^5 1k<n105).

The second line of each test case contains the string s s s of length n n n consisting of lowercase English letters.

It is guaranteed that the sum of n n n over all test cases does not exceed 1 0 5 10^5 105.

Output

For each test case, print the lexicographically smallest string after doing some (possibly, zero) steps.

Example
input

5
4 2
nima
5 3
panda
9 2
theforces
7 3
amirfar
6 4
rounds

output

aimn
aandp
ceefhorst
aafmirr
dnorsu

Note

In the first test case, we can obtain the string “aimn” using the following operations:

  1. Reverse the range [ 3 , 4 ] [3,4] [3,4]. The string turns into “niam”.
  2. Swap s 1 s_1 s1 and s 3 s_3 s3. The string turns into “ainm”.
  3. Reverse the range [ 3 , 4 ] [3,4] [3,4]. The string turns into “aimn”.

It can be proven that we cannot obtain any string lexicographically smaller than “aimn”. Therefore, “aimn” is the answer.

In the second test case, we can obtain the string “aandp” using the following operations:

  1. Swap s 3 s_3 s3 and s 5 s_5 s5. The string turns into “paadn”.
  2. Swap s 1 s_1 s1 and s 3 s_3 s3. The string turns into “aapdn”.
  3. Swap s 3 s_3 s3 and s 5 s_5 s5. The string turns into “aandp”.

It can be proven that we cannot obtain any string lexicographically smaller than “aandp”. Therefore, “aandp” is the answer.

Tutorial
由题意得,对于每个 i ( 1 ≥ i ≥ n − 2 ) i(1 \ge i \ge n - 2) i(1in2),都可以交换 s i s_i si s i + 2 s_{i + 2} si+2,这一操作其实可以理解为对于这个字符串 s s s,其奇数下标位置之间可以相互交换,偶数下标位置之间也可以相互交换,所以无论 k k k 取什么值,奇数位置之间和偶数位置之间都可以相互交换,那么当什么时候可以使奇数下标位置和偶数下标位置之间交换呢?

这个时候就需要对 k k k 进行讨论,如果 k k k 是奇数,那么必定可以存在 s 1 s_1 s1 s 1 + k s_{1 + k} s1+k 交换,此时使原本处于奇数下标位置的字符交换到了偶数下标位置,此时说明整个字符串都可以任意排序

综上所述,可以分为以下两种情况讨论:

  • k k k 为奇数时,直接对字符串 s s s 进行排序即可,因为此时任意两个字符都可以通过交换到达想要的位置
  • k k k 为偶数时,可以在奇数下标位置之间进行排序,偶数下标位置纸巾进行排序

Solution

#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define endl '\n'
#define int long long

void solve() {
    int n, k;
    string s;
    cin >> n >> k >> s;
    if (k & 1) {
        vector<pair<char, int>> a;
        for (int i = 0; i < n; ++i) {
            a.emplace_back(s[i], i);
        }
        ranges::sort(a);
        string ans = string(" ", n);
        int l = 0, r = 1;
        for (PII ai : a) {
            if (ai.se & 1) {
                ans[r] = ai.fi;
                r += 2;
            } else {
                ans[l] = ai.fi;
                l += 2;
            }
        }
        cout << ans << endl;
    } else {
        ranges::sort(s);
        cout << s << endl;
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cout << fixed << setprecision(15);
    int test; cin >> test; while (test--)
    solve();
    return 0;
}

C. Divisor Chain

time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
outputL: standard output

You are given an integer x x x. Your task is to reduce x x x to 1 1 1.

To do that, you can do the following operation:

  • select a divisor d d d of x x x, then change x x x to x − d x-d xd, i.e. reduce x x x by d d d. (We say that d d d is a divisor of x x x if d d d is an positive integer and there exists an integer q q q such that x = d ⋅ q x = d \cdot q x=dq.)

There is an additional constraint: you cannot select the same value of d d d more than twice.

For example, for x = 5 x=5 x=5, the following scheme is invalid because 1 1 1 is selected more than twice: 5 → − 1 4 → − 1 3 → − 1 2 → − 1 1 5\xrightarrow{-1}4\xrightarrow{-1}3\xrightarrow{-1}2\xrightarrow{-1}1 51 41 31 21 1. The following scheme is however a valid one: 5 → − 1 4 → − 2 2 → − 1 1 5\xrightarrow{-1}4\xrightarrow{-2}2\xrightarrow{-1}1 51 42 21 1.

Output any scheme which reduces x x x to 1 1 1 with at most 1000 1000 1000 operations. It can be proved that such a scheme always exists.

Input

Each test contains multiple test cases. The first line contains the number of test cases t t t ( 1 ≤ t ≤ 1000 1 \le t \le 1000 1t1000). The description of the test cases follows.

The only line of each test case contains a single integer x x x ( 2 ≤ x ≤ 1 0 9 2\le x \le 10^{9} 2x109).

Output

For each test case, output two lines.

The first line should contain an integer k k k ( 1 ≤ k ≤ 1001 1 \le k \le 1001 1k1001).

The next line should contain k k k integers a 1 , a 2 , … , a k a_1,a_2,\ldots,a_k a1,a2,,ak, which satisfy the following:

  • a 1 = x a_1=x a1=x;
  • a k = 1 a_k=1 ak=1;
  • for each 2 ≤ i ≤ k 2 \le i \le k 2ik, the value ( a i − 1 − a i ) (a_{i-1}-a_i) (ai1ai) is a divisor of a i − 1 a_{i-1} ai1. Each number may occur as a divisor at most twice.

Example
input

3
3
5
14

output

3
3 2 1
4
5 4 2 1
6
14 12 6 3 2 1

Note

In the first test case, we use the following scheme: 3 → − 1 2 → − 1 1 3\xrightarrow{-1}2\xrightarrow{-1}1 31 21 1.

In the second test case, we use the following scheme: 5 → − 1 4 → − 2 2 → − 1 1 5\xrightarrow{-1}4\xrightarrow{-2}2\xrightarrow{-1}1 51 42 21 1.

In the third test case, we use the following scheme: 14 → − 2 12 → − 6 6 → − 3 3 → − 1 2 → − 1 1 14\xrightarrow{-2}12\xrightarrow{-6}6\xrightarrow{-3}3\xrightarrow{-1}2\xrightarrow{-1}1 142 126 63 31 21 1.

Tutorial
个人认为本题方法比较巧妙,先将 x x x 转换为二进制数,每次将最低位的 1 直接减去即可,因为高位 1 一定可以拆分为多个低位 1,即满足 x = d ⋅ q x = d \cdot q x=dq,这样一直拆解到只剩一位 1

拆解到只剩一位 1 后,就很简单处理了,直接每次减去当前数的一半,这样必定不会出现两次连续一样的 d d d,最后也必定是以 1 结束

Solution

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long
#define lowbit(x) x & -x
#define sqrt(x) __builtin_sqrt(x)

void solve() {
    int x;
    cin >> x;
    vector<int> ans;
    while (popcount(x) > 1) {
        ans.emplace_back(x);
        x -= lowbit(x);
    }
    while (x >= 1) {
        ans.emplace_back(x);
        x >>= 1;
    }
    int l = ans.size();
    cout << l << endl;
    for (int i = 0; i < l; ++i) {
        cout << ans[i] << " \n"[i == l - 1];
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cout << fixed << setprecision(15);
    int test; cin >> test; while (test--)
    solve();
    return 0;
}

D. Matrix Cascade

time limit per test: 2 second
memory limit per test: 256 megabytes
input: standard input
outputL: standard output

There is a matrix of size n × n n \times n n×n which consists of 0s and 1s. The rows are numbered from 1 1 1 to n n n from top to bottom, the columns are numbered from 1 1 1 to n n n from left to right. The cell at the intersection of the x x x-th row and the y y y-th column is denoted as ( x , y ) (x, y) (x,y).

AquaMoon wants to turn all elements of the matrix to 0s. In one step she can perform the following operation:

  • Select an arbitrary cell, let it be ( i , j ) (i, j) (i,j), then invert the element in ( i , j ) (i, j) (i,j) and also invert all elements in cells ( x , y ) (x, y) (x,y) for x > i x > i x>i and x − i ≥ ∣ y − j ∣ x - i \ge \left|y - j\right| xiyj. To invert a value means to change it to the opposite: 0 changes to 1, 1 changes to 0.

Help AquaMoon determine the minimum number of steps she need to perform to turn all elements of the matrix to 0s. We can show that an answer always exists.

Input

Each test contains multiple test cases. The first line contains the number of test cases t t t ( 1 ≤ t ≤ 1 0 5 1 \le t \le 10^5 1t105). The description of the test cases follows.

The first line of each test case contains an integer n n n ( 2 ≤ n ≤ 3000 2 \le n \le 3000 2n3000).

The i i i-th of the following n n n lines contains a binary string only of characters 0 and 1, of length n n n.

It is guaranteed that the sum of n 2 n^2 n2 over all test cases does not exceed 9   000   000 9\,000\,000 9000000.

Output

For each test case, print the minimum number of steps.

Example
input

3
5
00100
01110
11111
11111
11111
3
100
110
110
6
010101
111101
011110
000000
111010
001110

output

1
2
15

Note

In the first test case, we can use the following scheme:

  1. perform the operation on the cell ( 1 , 3 ) (1, 3) (1,3).

Clearly, the elements of the initial matrix are not all 0, so at least one operation is required. Thus, 1 1 1 is the answer.

In the second test case, we use the following scheme:

  1. perform the operation on the cell ( 3 , 3 ) (3, 3) (3,3);
  2. perform the operation on the cell ( 1 , 1 ) (1, 1) (1,1).

It can be shown that there is no way to convert all elements to 0s in 0 0 0 or 1 1 1 steps, so the answer is exactly 2 2 2.

Tutorial

由题意不难得出,每次反转的范围是以一个点为顶点,以等腰三角形向下延伸的这个三角形区域,所以就需要从第一层到最后一层遍历所有的点一次,遇到一个需要反转的点答案就加一(这一过程有点像 D P DP DP ,但总体来说也算是前缀和?)

在从第一层到最后一层的遍历中,需要将前缀和转换为三个前缀和数组的累加:一个从上到下的前缀和数组、一个从左上到右下的前缀和数组、一个从右上到左下的前缀和数组,从上到下一层一层判断,由于利用到了前缀和数组,所以时间复杂度为 O ( n 2 ) O(n^2) O(n2)

Solution

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long

const int N = 3005;
int a[N][N], b[N][N], c[N][N], d[N][N];

void solve() {
    int n ,ans = 0;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < n; ++j) {
            a[i][j] = s[j] - '0';
            b[i][j] = c[i][j] = d[i][j] = 0;
        }
    }
    for (int x = 0; x < n; ++x) {
        for (int y = 0; y < n; ++y) {
            if (x > 0) {
                b[x][y] ^= b[x - 1][y];
                if (y > 0) {
                    c[x][y] ^= c[x - 1][y - 1];
                }
                if (y < n - 1) {
                    d[x][y] ^= d[x - 1][y + 1];
                }
            }
            a[x][y] ^= (b[x][y] ^= c[x][y] ^ d[x][y]);
            if (a[x][y]) {
                ans++;
                b[x][y] ^= 1;
                c[x][y] ^= 1;
                d[x][y] ^= 1;
            }
        }
    }
    cout << ans << endl;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cout << fixed << setprecision(15);
    int test; cin >> test; while (test--)
    solve();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值