Codeforces Round #653 (Div. 3) [A,B,C,D,E1] 题解报告

目录

    • A. Required Remainder
      • Input
      • Output
      • Example
        • input
        • output
      • Note
      • 题意
      • 思路
      • my Accepted code
    • B. Multiply by 2, divide by 6
      • Example
        • input
        • output
      • Note
      • 题意
      • 思路
      • my Accepted code
    • C. Move Brackets
      • Input
      • Output
      • Example
        • input
        • output
      • Note
      • 题意
      • 思路
      • my Accepted code
    • D. Zero Remainder Array
      • Input
      • Output
      • Example
        • input
        • output
      • Note
      • 题意
      • 思路
      • my Accepted code
    • E1. Reading Books (easy version)
      • Input
      • Output
      • Examples
        • input
        • output
        • input
        • output
        • input
        • output
      • 题意
      • 思路
      • my Accepted code

[比赛传送门]

A. Required Remainder

You are given three integers x,y and n. Your task is to find the maximum integer k such that 0≤k≤n that kmodx=y, where mod is modulo operation. Many programming languages use percent operator % to implement it.

In other words, with given x,y and n you need to find the maximum possible integer from 0 to n that has the remainder y modulo x.

You have to answer t independent test cases. It is guaranteed that such k exists for each test case.

Input

The first line of the input contains one integer t (1≤t≤5⋅104) — the number of test cases. The next t lines contain test cases.

The only line of the test case contains three integers x,y and n (2≤x≤109; 0≤y9).

It can be shown that such k always exists under the given constraints.

Output

For each test case, print the answer — maximum non-negative integer k such that 0≤k≤n and kmodx=y. It is guaranteed that the answer always exists.

Example

input

7
7 5 12345
5 0 4
10 5 15
17 8 54321
499999993 9 1000000000
10 5 187
2 0 999999999

output

12339
0
15
54306
999999995
185
999999998

Note

In the first test case of the example, the answer is 12339=7⋅1762+5 (thus, 12339mod7=5). It is obvious that there is no greater integer not exceeding 12345 which has the remainder 5 modulo 7.

题意

找到n内满足减去y后可以被x整除的最大数

思路

判断floor(n/x)*x+y是否大于n,若是,输出(floor(n/x)-1)*x+y,否则输出floor(n/x)*x+y

my Accepted code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ll long long
#define db double
#define inf INT_MAX
#define s(a, n) memset(a, n, sizeof(a))
#define rep(l, a, b) for (ll l = a; l < b; ++l)
#define per(l, a, b) for (ll l = a; l >= b; --l)
#define debug(a) cout << '#' << a << '#' << endl

using namespace std;
bool fi = true;
const unsigned long long MOD = 1e9 + 7;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int t;
    cin >> t;
    while (t--) {
        int x, y, n;
        cin >> x >> y >> n;
        int a = n / x;
        if (n - a * x >= y) {
            cout << a * x + y << endl;
        } else {
            cout << (a - 1) * x + y << endl;
        }
    }
}

在这里插入图片描述

B. Multiply by 2, divide by 6

You are given an integer n. In one move, you can either multiply n by two or divide n by 6 (if it is divisible by 6 without the remainder).

Your task is to find the minimum number of moves needed to obtain 1 from n or determine if it’s impossible to do that.

You have to answer t independent test cases.

Input
The first line of the input contains one integer t (1≤t≤2⋅104) — the number of test cases. Then t test cases follow.

The only line of the test case contains one integer n (1≤n≤109).

Output
For each test case, print the answer — the minimum number of moves needed to obtain 1 from n if it’s possible to do that or -1 if it’s impossible to obtain 1 from n.

Example

input

7
1
2
3
12
12345
15116544
387420489

output

0
-1
2
-1
-1
12
36

Note

Consider the sixth test case of the example. The answer can be obtained by the following sequence of moves from the given integer 15116544:

1.Divide by 6 and get 2519424;
2.divide by 6 and get 419904;
3.divide by 6 and get 69984;
4.divide by 6 and get 11664;
5.multiply by 2 and get 23328;
6.divide by 6 and get 3888;
7.divide by 6 and get 648;
8.divide by 6 and get 108;
9.multiply by 2 and get 216;
10.divide by 6 and get 36;
11.divide by 6 and get 6;
12.divide by 6 and get 1.

题意

给你一个数,你可以对它进行两种操作:

  • 除以6
  • 乘以2

若能在有限次回合内依据以上两种操作将这个数化为1,则输出需要的回合数。
否则输出-1

思路

无思路,暴力,当回合数超过200还没变成1,输出-1

my Accepted code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ll long long
#define db double
#define inf INT_MAX
#define s(a, n) memset(a, n, sizeof(a))
#define rep(l, a, b) for (ll l = a; l < b; ++l)
#define per(l, a, b) for (ll l = a; l >= b; --l)
#define debug(a) cout << '#' << a << '#' << endl

using namespace std;
bool fi = true;
const unsigned long long MOD = 1e9 + 7;
ll count1;

ll dfs(ll a) {
    if (count1 > 200 && a != 1) return -1;
    if (a == 1) return count1;
    if (a % 6 != 0) {
        count1++;
        return dfs(2 * a);
    } else {
        count1++;
        return dfs(a / 6);
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int t;
    cin >> t;
    while (t--) {
        ll n;
        cin >> n;
        count1 = 0;
        ll ans = dfs(n);
        cout << ans << endl;
    }
}

在这里插入图片描述

C. Move Brackets

You are given a bracket sequence s of length n, where n is even (divisible by two). The string s consists of n2 opening brackets ‘(’ and n2 closing brackets ‘)’.

In one move, you can choose exactly one bracket and move it to the beginning of the string or to the end of the string (i.e. you choose some index i, remove the i-th character of s and insert it before or after all remaining characters of s).

Your task is to find the minimum number of moves required to obtain regular bracket sequence from s. It can be proved that the answer always exists under the given constraints.

Recall what the regular bracket sequence is:

“()” is regular bracket sequence;
if s is regular bracket sequence then “(” + s + “)” is regular bracket sequence;
if s and t are regular bracket sequences then s + t is regular bracket sequence.
For example, “()()”, “(())()”, “(())” and “()” are regular bracket sequences, but “)(”, “()(” and “)))” are not.

You have to answer t independent test cases.

Input

The first line of the input contains one integer t (1≤t≤2000) — the number of test cases. Then t test cases follow.

The first line of the test case contains one integer n (2≤n≤50) — the length of s. It is guaranteed that n is even. The second line of the test case containg the string s consisting of n2 opening and n2 closing brackets.

Output

For each test case, print the answer — the minimum number of moves required to obtain regular bracket sequence from s. It can be proved that the answer always exists under the given constraints.

Example

input

4
2
)(
4
()()
8
())()()(
10
)))((((())

output

1
0
1
3

Note

In the first test case of the example, it is sufficient to move the first bracket to the end of the string.

In the third test case of the example, it is sufficient to move the last bracket to the beginning of the string.

In the fourth test case of the example, we can choose last three openning brackets, move them to the beginning of the string and obtain “((()))(())”.

题意

给你一串由括号组成的字符串,左右括号数相等,但可能不匹配。
需要你求出将其中括号移动几次可以完成匹配

思路

设置一个栈存放(,一个ans统计不匹配的),不匹配的)数即为需要移动的次数,即ans的值。
遇到(压入栈,当遇到)而栈不为空时,把栈顶元素pop掉,若栈为空时,ans++。

my Accepted code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ll long long
#define db double
#define inf INT_MAX
#define s(a, n) memset(a, n, sizeof(a))
#define rep(l, a, b) for (ll l = a; l < b; ++l)
#define per(l, a, b) for (ll l = a; l >= b; --l)
#define debug(a) cout << '#' << a << '#' << endl

using namespace std;
bool fi = true;
const unsigned long long MOD = 1e9 + 7;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        string a;
        cin >> a;
        stack<char> s;
        int ans = 0;
        rep(i, 0, n) {
            if (a[i] == '(')
                s.push(a[i]);
            else if (s.empty())
                ans++;
            else {
                s.pop();
            }
        }
        cout << ans << endl;
    }
}

在这里插入图片描述

D. Zero Remainder Array

You are given an array a consisting of n positive integers.

Initially, you have an integer x=0. During one move, you can do one of the following two operations:

Choose exactly one i from 1 to n and increase ai by x (ai:=ai+x), then increase x by 1 (x:=x+1).
Just increase x by 1 (x:=x+1).
The first operation can be applied no more than once to each i from 1 to n.

Your task is to find the minimum number of moves required to obtain such an array that each its element is divisible by k (the value k is given).

You have to answer t independent test cases.

Input

The first line of the input contains one integer t (1≤t≤2⋅104) — the number of test cases. Then t test cases follow.

The first line of the test case contains two integers n and k (1≤n≤2⋅105;1≤k≤109) — the length of a and the required divisior. The second line of the test case contains n integers a1,a2,…,an (1≤ai≤109), where ai is the i-th element of a.

It is guaranteed that the sum of n does not exceed 2⋅105 (∑n≤2⋅105).

Output

For each test case, print the answer — the minimum number of moves required to obtain such an array that each its element is divisible by k.

Example

input

5
4 3
1 2 1 3
10 6
8 7 1 8 3 7 5 10 8 9
5 10
20 100 50 20 100500
10 25
24 24 24 24 24 24 24 24 24 24
8 8
1 2 3 4 5 6 7 8

output

6
18
0
227
8

Note

Consider the first test case of the example:

x=0, a=[1,2,1,3]. Just increase x;
x=1, a=[1,2,1,3]. Add x to the second element and increase x;
x=2, a=[1,3,1,3]. Add x to the third element and increase x;
x=3, a=[1,3,3,3]. Add x to the fourth element and increase x;
x=4, a=[1,3,3,6]. Just increase x;
x=5, a=[1,3,3,6]. Add x to the first element and increase x;
x=6, a=[6,3,3,6]. We obtained the required array.
Note that you can’t add x to the same element more than once.

题意

给你一个数列a,一个k,和一个x,x为0;
你有一下两种操作:

  • x++
  • a[i]+=x,x++
    (i可以为数组长度内的任意位置)

问将每个元素化为 ‘可以被k整除的数’ 需要几个回合

思路

开一个mapkn,统计x需要增加多少轮k
对数列中每个数 ai ,如果 ai%k 为 0 ,则跳过;
如果不为0,kn[ai%k]++;同时统计最大kn及最大kn的ai%k。
若出现当前kn与最大kn相等,即表示x需要增加的轮数相等,则统计最小ai%k,当同一轮内,ai%k越小,x则需要更多的回合达到 (ai+x)%k ==0.
最后根据统计的最大kn -> maxt ,和最小 ai%k -> minnum ,得出答案为 :(maxt-1)*k+(k-minnum)+1(由于x是从0开始,所以答案要加1)

my Accepted code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ll long long
#define db double
#define inf INT_MAX
#define s(a, n) memset(a, n, sizeof(a))
#define rep(l, a, b) for (ll l = a; l < b; ++l)
#define per(l, a, b) for (ll l = a; l >= b; --l)
#define debug(a) cout << '#' << a << '#' << endl

using namespace std;
bool fi = true;
const unsigned long long MOD = 1e9 + 7;
ll t, n, k, a;
ll ans;

map<ll, ll> kn;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> t;
    while (t--) {
        cin >> n >> k;
        ll minnum = MOD;
        ll maxt = 0;
        bool find = false;
        rep(i, 0, n) {
            cin >> a;
            ll l = a % k;
            if (l == 0) {
                continue;
            } else {
                find = true;
                kn[l]++;
                if (maxt < kn[l]) {
                    maxt = kn[l];
                    minnum = l;
                }
                if (maxt == kn[l]) {
                    minnum = min(minnum, l);
                }
            }
        }
        if (find) {
            ans = (k - minnum) + (maxt - 1) * k;
            cout << ans + 1 << endl;
        } else {
            cout << 0 << endl;
        }
        kn.erase(kn.begin(), kn.end());
    }
}

在这里插入图片描述

E1. Reading Books (easy version)

Easy and hard versions are actually different problems, so read statements of both problems completely and carefully.

Summer vacation has started so Alice and Bob want to play and joy, but… Their mom doesn’t think so. She says that they have to read some amount of books before all entertainments. Alice and Bob will read each book together to end this exercise faster.

There are n books in the family library. The i-th book is described by three integers: ti — the amount of time Alice and Bob need to spend to read it, ai (equals 1 if Alice likes the i-th book and 0 if not), and bi (equals 1 if Bob likes the i-th book and 0 if not).

So they need to choose some books from the given n books in such a way that:

Alice likes at least k books from the chosen set and Bob likes at least k books from the chosen set;
the total reading time of these books is minimized (they are children and want to play and joy as soon a possible).
The set they choose is the same for both Alice an Bob (it’s shared between them) and they read all books together, so the total reading time is the sum of ti over all books that are in the chosen set.

Your task is to help them and find any suitable set of books or determine that it is impossible to find such a set.

Input

The first line of the input contains two integers n and k (1≤k≤n≤2⋅105).

The next n lines contain descriptions of books, one description per line: the i-th line contains three integers ti, ai and bi (1≤ti≤104, 0≤ai,bi≤1), where:

ti — the amount of time required for reading the i-th book;
ai equals 1 if Alice likes the i-th book and 0 otherwise;
bi equals 1 if Bob likes the i-th book and 0 otherwise.

Output

If there is no solution, print only one integer -1. Otherwise print one integer T — the minimum total reading time of the suitable set of books.

Examples

input

8 4
7 1 1
2 1 1
4 0 1
8 1 1
1 0 1
1 1 1
1 0 1
3 0 0

output

18

input

5 2
6 0 0
9 0 0
1 0 1
2 1 1
5 1 0

output

8

input

5 3
3 0 0
2 1 0
3 1 0
5 0 1
3 0 1

output

-1

题意

一开始没有看懂题目(阅读理解不行),后面是看了dalao的题解才看懂题意的。
有n本书,这本书的阅读时间为t,如果Alice喜欢,a为1,否则为0;如果Bob喜欢,b为1,否则为0;
Alice和Bob要各选k本自己喜欢的数来读,同时且两人读的是同一套书
即Alice选k本,Bob选k本,若他们选的数都一样,即他们只要读k本书,花费的时间是这k本书的和。
若他们选的有k1本相同,则他们要读k1+2*(k-k1)本书,即对方选的书,自己也要看完。
求最短需要花多少时间

思路

这题可以用vector然后排序,将只有Alice喜欢的书和只有Bob喜欢的书组合在一起(依次将时间最短的书组合在一起),放在Alice和Bob都喜欢的书里面,然后对vector进行排序
但是这题也可以使用一个我没用过的STL:propriority_queue(优先队列)
设定优先队列为降序

	priority_queue<int, vector<int>, greater<int> > A, B, all;

这样元素无论以什么顺序入队,出队的元素都是队列中最小的
学到了.jpg
具体实现参见代码

my Accepted code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ll long long
#define db double
#define inf INT_MAX
#define s(a, n) memset(a, n, sizeof(a))
#define rep(l, a, b) for (ll l = a; l < b; ++l)
#define per(l, a, b) for (ll l = a; l >= b; --l)
#define debug(a) cout << '#' << a << '#' << endl

using namespace std;
bool fi = true;
const unsigned long long MOD = 1e9 + 7;

priority_queue<int, vector<int>, greater<int> > A, B, all;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n, k;
    cin >> n >> k;
    rep(i, 0, n) {
        int t, a, b;
        cin >> t >> a >> b;
        if (a && b) {
            all.push(t);
        } else if (a) {
            A.push(t);
        } else if (b) {
            B.push(t);
        }
    }
    while (!A.empty() && !B.empty()) {
        int t = A.top() + B.top();
        all.push(t);
        A.pop();
        B.pop();
    }
    if (all.size() >= k) {
        ll ans = 0;
        rep(i, 0, k) {
            ans += all.top();
            all.pop();
        }
        cout << ans << endl;
    } else
        cout << -1 << endl;
}

在这里插入图片描述

你可能感兴趣的:(cf题解)