Codeforces Round #618 (Div. 2)(题解)

在这里插入图片描述
写在前面: C没做出来555,本来这次排名应该会高好多。。。

A. Non-zero

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Guy-Manuel and Thomas have an array a of n integers [a1,a2,…,an]. In one step they can add 1 to any element of the array. Formally, in one step they can choose any integer index i (1≤i≤n) and do ai:=ai+1.

If either the sum or the product of all elements in the array is equal to zero, Guy-Manuel and Thomas do not mind to do this operation one more time.

What is the minimum number of steps they need to do to make both the sum and the product of all elements in the array different from zero? Formally, find the minimum number of steps to make a1+a2+ … +an≠0 and a1⋅a2⋅ … ⋅an≠0.

Input
Each test contains multiple test cases.

The first line contains the number of test cases t (1≤t≤103). The description of the test cases follows.

The first line of each test case contains an integer n (1≤n≤100) — the size of the array.

The second line of each test case contains n integers a1,a2,…,an (−100≤ai≤100) — elements of the array .

Output
For each test case, output the minimum number of steps required to make both sum and product of all elements in the array different from zero.

Example
inputCopy
4
3
2 -1 -1
4
-1 0 0 1
2
-1 2
3
0 -2 1
outputCopy
1
2
0
2
Note
In the first test case, the sum is 0. If we add 1 to the first element, the array will be [3,−1,−1], the sum will be equal to 1 and the product will be equal to 3.

In the second test case, both product and sum are 0. If we add 1 to the second and the third element, the array will be [−1,1,1,1], the sum will be equal to 2 and the product will be equal to −1. It can be shown that fewer steps can’t be enough.

In the third test case, both sum and product are non-zero, we don’t need to do anything.

In the fourth test case, after adding 1 twice to the first element the array will be [2,−2,1], the sum will be 1 and the product will be −4.
题意: 相加和相乘都不为0.
思路: 输入遇到0就加一,最后如果总和为0则再加1。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <cmath>
#include <set>
 
using namespace std;
 
#define endl '\n'
 
typedef long long ll;
 
vector<ll>v;
string s;
 
int main()
{
    int t;
    cin >> t;
 
    while (t--)
    {
        int n;
        cin >> n;
        int ans = 0;
 
        ll s = 0;
 
        for (int i = 0; i < n; ++i)
        {
            ll x;
            cin >> x;
            s += x;
            if (x == 0)
            {
                s++;
                ans++;
            }
        }
            if (s == 0)
            {
                ans++;
                s++;
            }
 
        cout << ans << endl;
    }
return 0;
}

B. Assigning to Classes

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Reminder: the median of the array [a1,a2,…,a2k+1] of odd number of elements is defined as follows: let [b1,b2,…,b2k+1] be the elements of the array in the sorted order. Then median of this array is equal to bk+1.

There are 2n students, the i-th student has skill level ai. It’s not guaranteed that all skill levels are distinct.

Let’s define skill level of a class as the median of skill levels of students of the class.

As a principal of the school, you would like to assign each student to one of the 2 classes such that each class has odd number of students (not divisible by 2). The number of students in the classes may be equal or different, by your choice. Every student has to be assigned to exactly one class. Among such partitions, you want to choose one in which the absolute difference between skill levels of the classes is minimized.

What is the minimum possible absolute difference you can achieve?

Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤104). The description of the test cases follows.

The first line of each test case contains a single integer n (1≤n≤105) — the number of students halved.

The second line of each test case contains 2n integers a1,a2,…,a2n (1≤ai≤109) — skill levels of students.

It is guaranteed that the sum of n over all test cases does not exceed 105.

Output
For each test case, output a single integer, the minimum possible absolute difference between skill levels of two classes of odd sizes.

Example
inputCopy
3
1
1 1
3
6 5 4 1 2 3
5
13 4 20 13 2 5 8 3 17 16
outputCopy
0
1
5
Note
In the first test, there is only one way to partition students — one in each class. The absolute difference of the skill levels will be |1−1|=0.

In the second test, one of the possible partitions is to make the first class of students with skill levels [6,4,2], so that the skill level of the first class will be 4, and second with [5,1,3], so that the skill level of the second class will be 3. Absolute difference will be |4−3|=1.

Note that you can’t assign like [2,3], [6,5,4,1] or [], [6,5,4,1,2,3] because classes have even number of students.

[2], [1,3,4] is also not possible because students with skills 5 and 6 aren’t assigned to a class.

In the third test you can assign the students in the following way: [3,4,13,13,20],[2,5,8,16,17] or [3,8,17],[2,4,5,13,13,16,20]. Both divisions give minimal possible absolute difference.
题意: 将数组划分成两段奇数块,然后中位数相减,求最小。
思路: 排序后直接减中间两个即可。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <cmath>
#include <set>
 
using namespace std;
 
#define endl '\n'
 
typedef long long ll;
 
ll a[300005];
 
int main()
{
    int t;
    cin >> t;
 
    while (t--)
    {
        int n;
        cin >> n;
        for (int i = 0; i < 2 * n; ++i)
            cin >> a[i];
        sort(a, a + 2 * n);
 
        cout << a[n] - a[n - 1] << endl;
    }
return 0;
}

C. Anu Has a Function

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Anu has created her own function f: f(x,y)=(x|y)−y where | denotes the bitwise OR operation. For example, f(11,6)=(11|6)−6=15−6=9. It can be proved that for any nonnegative numbers x and y value of f(x,y) is also nonnegative.

She would like to research more about this function and has created multiple problems for herself. But she isn’t able to solve all of them and needs your help. Here is one of these problems.

A value of an array [a1,a2,…,an] is defined as f(f(…f(f(a1,a2),a3),…an−1),an) (see notes). You are given an array with not necessarily distinct elements. How should you reorder its elements so that the value of the array is maximal possible?

Input
The first line contains a single integer n (1≤n≤105).

The second line contains n integers a1,a2,…,an (0≤ai≤109). Elements of the array are not guaranteed to be different.

Output
Output n integers, the reordering of the array with maximum value. If there are multiple answers, print any.

Examples
inputCopy
4
4 0 11 6
outputCopy
11 6 4 0
inputCopy
1
13
outputCopy
13
Note
In the first testcase, value of the array [11,6,4,0] is f(f(f(11,6),4),0)=f(f(9,4),0)=f(9,0)=9.

[11,4,0,6] is also a valid answer.
题意: 有一个函数,f(x, y) = x | y - y,所有数字求一个排序得到结果最大。
思路: 这题当时没做出来,看了大佬的思路懂了。
遇见位运算的题目首先应该想到拆项。
观察特征(第 i 位)
xi = 1, yi = 1 – 0
xi = 0, yi = 1 – 0
xi = 1, yi = 0 – 1
可以发现,如果所有数某一位的1的个数>=2,那最后会变成0,只有某一位只有一个1,对整体贡献最大。所以就要找出这个数字,第一个输出即可。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <cmath>
#include <set>

using namespace std;

#define endl '\n'

typedef long long ll;

ll a[300005];

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

    for (int i = 1; i <= n; ++i)
        cin >> a[i];

    int ans = 0;

    for (int i = 30; i >= 0; --i)
    {
        int cnt = 0, pos = 0;
        for (int j = 1; j <= n; ++j)
        {
            if (a[j] & (1 << i))
            {
                cnt++;
                pos = j;
            }
        }
        if (cnt == 1)
        {
            ans = pos;
            break;
        }
    }

    if (!ans)
    {
        for (int i = 1; i <= n; ++i)
        {
            if (i == 1)
                cout << a[i];
            else
                cout << " " << a[i];
        }
    }
    else
    {
        cout << a[ans];
        for (int i = 1; i <= n; ++i)
            if (i != ans)
                cout << " " << a[i];
    }


    return 0;
}

D. Aerodynamic

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Guy-Manuel and Thomas are going to build a polygon spaceship.

You’re given a strictly convex (i. e. no three points are collinear) polygon P which is defined by coordinates of its vertices. Define P(x,y) as a polygon obtained by translating P by vector (x,y)−→−−. The picture below depicts an example of the translation:

Define T as a set of points which is the union of all P(x,y) such that the origin (0,0) lies in P(x,y) (both strictly inside and on the boundary). There is also an equivalent definition: a point (x,y) lies in T only if there are two points A,B in P such that AB−→−=(x,y)−→−−. One can prove T is a polygon too. For example, if P is a regular triangle then T is a regular hexagon. At the picture below P is drawn in black and some P(x,y) which contain the origin are drawn in colored:

The spaceship has the best aerodynamic performance if P and T are similar. Your task is to check whether the polygons P and T are similar.

Input
The first line of input will contain a single integer n (3≤n≤105) — the number of points.

The i-th of the next n lines contains two integers xi,yi (|xi|,|yi|≤109), denoting the coordinates of the i-th vertex.

It is guaranteed that these points are listed in counterclockwise order and these points form a strictly convex polygon.

Output
Output “YES” in a separate line, if P and T are similar. Otherwise, output “NO” in a separate line. You can print each letter in any case (upper or lower).

Examples
inputCopy
4
1 0
4 1
3 4
0 3
outputCopy
YES
inputCopy
3
100 86
50 0
150 0
outputCopy
nO
inputCopy
8
0 0
1 0
2 1
3 3
4 6
3 6
2 5
1 3
outputCopy
YES
Note
The following image shows the first sample: both P and T are squares. The second sample was shown in the statements.
题意: 计算P和T是否相似。
思路: 认真看两张示意图,发现就是给定图形P用每一条边靠在原点上运动形成T。
所以,P与T相似要2个条件。
1、P的边数必须是偶数,
2、P的对边必须平行。
然后就好啦!

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <cmath>
#include <set>
 
using namespace std;
 
#define endl '\n'
 
typedef long long ll;
 
ll x[300005];
ll y[300005];
ll xx[300005];
ll yy[300005];
 
 
int main()
{
    int n;
    cin >> n;
 
    for (int i = 0; i < n; ++i)
        cin >> x[i] >> y[i];
 
    if (n % 2 == 1)
    {
        cout << "NO" << endl;
        return 0;
    }
 
    int f = 0;
 
    for (int i = 0; i < n; ++i)
    {
        if (i < n - 1)
        {
            xx[i] = x[i + 1] - x[i];
            yy[i] = y[i + 1] - y[i];
        }
        else
        {
            xx[i] = x[0] - x[i];
            yy[i] = y[0] - y[i];
        }
    }
 
    for (int i = 0; i < n / 2; ++i)
    {
        int f1 = 1, f2 = 1, f3 = 1, f4 = 1;
 
        if (xx[i] < 0)
            f1 = -1;
        if (yy[i] < 0)
            f2 = -1;
        if (xx[i + n / 2] < 0)
            f3 = -1;
        if (yy[i + n / 2] < 0)
            f4 = -1;
        if (xx[i] == 0)
            f1 = 0;
        if (yy[i] == 0)
            f2 = 0;
        if (xx[i + n / 2] == 0)
            f3 = 0;
        if (yy[i + n / 2] == 0)
            f4 = 0;
 
        if (f1 * f2 == f3 * f4 && abs(xx[i]) == abs(xx[i + n / 2]) && abs(yy[i]) == abs(yy[i + n / 2]))
            f = 0;
        else
        {
            f = 1;
            break;
        }
    }
 
    if (f)
    {
        cout << "NO" << endl;
    }
    else
    {
        cout << "YES" << endl;
    }
 
    return 0;
}
发布了161 篇原创文章 · 获赞 7 · 访问量 7074

猜你喜欢

转载自blog.csdn.net/weixin_43778744/article/details/104242899