Codeforces Round #320 (Div. 2) [Bayan Thanks-Round] (ABCDE題解)

_TCgogogo_發表於2015-09-19

比賽連結:http://codeforces.com/contest/579


A. Raising Bacteria
time limit per test:1 second
memory limit per test:256 megabytes

You are a lover of bacteria. You want to raise some bacteria in a box.

Initially, the box is empty. Each morning, you can put any number of bacteria into the box. And each night, every bacterium in the box will split into two bacteria. You hope to see exactly x bacteria in the box at some moment.

What is the minimum number of bacteria you need to put into the box across those days?

Input

The only line containing one integer x (1 ≤ x ≤ 109).

Output

The only line containing one integer: the answer.

Sample test(s)
Input
5
Output
2
Input
8
Output
1
Note

For the first sample, we can add one bacterium in the box in the first day morning and at the third morning there will be 4 bacteria in the box. Now we put one more resulting 5 in the box. We added 2 bacteria in the process so the answer is 2.

For the second sample, we can put one in the first morning and in the 4-th morning there will be 8 in the box. So the answer is 1.

題目大意:求x的二進位制表示裡有幾個1

題目分析:位運算

#include <cstdio>

int main()
{
    int x, cnt = 0;
    scanf("%d", &x);
    while(x)
    {
        if(x & 1)
            cnt ++;
        x >>= 1;
    }
    printf("%d\n", cnt);
}


B. Finding Team Member
time limit per test:2 seconds
memory limit per test:256 megabytes

There is a programing contest named SnakeUp, 2n people want to compete for it. In order to attend this contest, people need to form teams of exactly two people. You are given the strength of each possible combination of two people. All the values of the strengths are distinct.

Every contestant hopes that he can find a teammate so that their team’s strength is as high as possible. That is, a contestant will form a team with highest strength possible by choosing a teammate from ones who are willing to be a teammate with him/her. More formally, two people A and B may form a team if each of them is the best possible teammate (among the contestants that remain unpaired) for the other one.

Can you determine who will be each person’s teammate?

Input

There are 2n lines in the input.

The first line contains an integer n (1 ≤ n ≤ 400) — the number of teams to be formed.

The i-th line (i > 1) contains i - 1 numbers ai1, ai2, ... , ai(i - 1). Here aij (1 ≤ aij ≤ 106, all aij are distinct) denotes the strength of a team consisting of person i and person j (people are numbered starting from 1.)

Output

Output a line containing 2n numbers. The i-th number should represent the number of teammate of i-th person.

Sample test(s)
Input
2
6
1 2
3 4 5
Output
2 1 4 3
Input
3
487060
3831 161856
845957 794650 976977
83847 50566 691206 498447
698377 156232 59015 382455 626960
Output
6 5 4 3 2 1
Note

In the first sample, contestant 1 and 2 will be teammates and so do contestant 3 and 4, so the teammate of contestant 1, 2, 3, 4 will be 2, 1, 4, 3 respectively.

題目大意:給一個下三角矩陣,要求選2n組人,每組兩人,aij表示i和j在一起的分數,每次選的結果都是當前可能的最大值,一個人只能在一組裡

題目分析:考慮aij只有1e6,果斷暴力搞,用vector存座標,然後從最大值往1列舉判斷即可,已經成組的標記一下

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int const MAX = 1e6 + 5;
int ans[MAX];
vector <int> vt[MAX];

int main()
{
    int n, tmp, ma = 0;
    scanf("%d", &n);
    n <<= 1;
    for(int i = 2; i <= n; i++)
    {
        for(int j = 1; j < i; j++)
        {
            scanf("%d", &tmp);
            vt[tmp].push_back(i);
            vt[tmp].push_back(j);
            ma = max(ma, tmp);
        }
    }
    for(int i = ma; i >= 1; i--)
    {
        int sz = vt[i].size();
        if(sz > 0)
        {
            int x = vt[i][0], y = vt[i][1];
            if(ans[x] == 0 && ans[y] == 0)
            {
                ans[x] = y;
                ans[y] = x;
            }
        }
    }
    for(int i = 1; i < n; i++)
        printf("%d ", ans[i]);
    printf("%d\n", ans[n]);
}



C. A Problem about Polyline
time limit per test:1 second
memory limit per test:256 megabytes

There is a polyline going through points (0, 0) – (x, x) – (2x, 0) – (3x, x) – (4x, 0) – ... - (2kx, 0) – (2kx + x, x) – ....

We know that the polyline passes through the point (a, b). Find minimum positive value x such that it is true or determine that there is no such x.

Input

Only one line containing two positive integers a and b (1 ≤ a, b ≤ 109).

Output

Output the only line containing the answer. Your answer will be considered correct if its relative or absolute error doesn't exceed 10 - 9. If there is no such x then output  - 1 as the answer.

Sample test(s)
Input
3 1
Output
1.000000000000
Input
1 3
Output
-1
Input
4 1
Output
1.250000000000
Note

You can see following graphs for sample 1 and sample 3.


題目大意:求最小的x使得,點(a,b)在這個鋸齒圖形上


題目分析:首先由於斜率為正負1,可以得到點(a,b)兩邊在x軸上的點座標為(a-b,0)和(a+b,0),一個週期T=2b,所以,通過(a-b)/2b和(a+b)/2b可以得到以(a,b)為頂點的圖形的週期範圍,很難說清楚,畫個圖一下子就能看出來,顯然以(a+b)/2b的更優,因為將它的x提高,它的邊界線可以更快的經過(a,b)點,這裡必須畫圖,說不清楚,所以答案就是(a+b)/2T了,注意a<b顯然不可能

#include <cstdio>

int main()
{
    int a, b;
    scanf("%d %d", &a, &b);
    if(a < b)
    {
        printf("-1\n");
        return 0;
    }
    int T = (a + b) / 2 / b;
    double ans = (double) (a + b) / (double) T / 2.0;
    printf("%.10f\n", ans);
}



D. "Or" Game
time limit per test:2 seconds
memory limit per test:256 megabytes

You are given n numbers a1, a2, ..., an. You can perform at most k operations. For each operation you can multiply one of the numbers by x. We want to make as large as possible, where denotes the bitwise OR.

Find the maximum possible value of after performing at most k operations optimally.

Input

The first line contains three integers n, k and x (1 ≤ n ≤ 200 000, 1 ≤ k ≤ 10, 2 ≤ x ≤ 8).

The second line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 109).

Output

Output the maximum value of a bitwise OR of sequence elements after performing operations.

Sample test(s)
Input
3 1 2
1 1 1
Output
3
Input
4 2 3
1 2 4 8
Output
79
Note

For the first sample, any possible choice of doing one operation will result the same three numbers 1, 1, 2 so the result is .

For the second sample if we multiply 8 by 3 two times we'll get 72. In this case the numbers will become 1, 2, 4, 72 so the OR value will be 79 and is the largest possible result.


題目大意:n個數字,可以對任意一個數字乘x,最多乘k次,現在求乘完後的序列的或和最大是多少


題目分析:首先確定k次必須全都乘到一個數字上,因為每乘1次二進位制最高位至少左移一位,這樣或出來的結果肯定是最大的,但是注意不是乘當前最大的那個數,比如1010和1001,分別成2得10100和10010,假設我要或的數是10100那顯然後面的更大,因此要列舉每個數,還要預處理字首/字尾或和,然後O(n)列舉乘的那個數字取最大即可

#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = 2e5 + 5;
ll l[MAX], r[MAX], a[MAX];

int main()
{
    int n, k, x;
    scanf("%d %d %d", &n, &k, &x);
    for(int i = 1; i <= n; i++)
        scanf("%I64d", &a[i]);
    for(int i = 1; i <= n; i++)
        l[i] = l[i - 1] | a[i];
    for(int i = n; i >= 1; i--)
        r[i] = r[i + 1] | a[i];
    ll tmp = 1;
    for(int i = 0; i < k; i++)
        tmp *= x;
    ll ans = 0;
    for(int i = 1; i <= n; i++)
        ans = max(ans, l[i - 1] | (a[i] * tmp) | r[i + 1]);
    printf("%I64d\n", ans);
}



E. Weakness and Poorness
time limit per test:2 seconds
memory limit per test:256 megabytes

You are given a sequence of n integers a1, a2, ..., an.

Determine a real number x such that the weakness of the sequence a1 - x, a2 - x, ..., an - x is as small as possible.

The weakness of a sequence is defined as the maximum value of the poorness over all segments (contiguous subsequences) of a sequence.

The poorness of a segment is defined as the absolute value of sum of the elements of segment.

Input

The first line contains one integer n (1 ≤ n ≤ 200 000), the length of a sequence.

The second line contains n integers a1, a2, ..., an (|ai| ≤ 10 000).

Output

Output a real number denoting the minimum possible weakness of a1 - x, a2 - x, ..., an - x. Your answer will be considered correct if its relative or absolute error doesn't exceed 10 - 6.

Sample test(s)
Input
3
1 2 3
Output
1.000000000000000
Input
4
1 2 3 4
Output
2.000000000000000
Input
10
1 10 2 9 3 8 4 7 5 6
Output
4.500000000000000
Note

For the first case, the optimal value of x is 2 so the sequence becomes  - 1, 0, 1 and the max poorness occurs at the segment "-1" or segment "1". The poorness value (answer) equals to 1 in this case.

For the second sample the optimal value of x is 2.5 so the sequence becomes  - 1.5,  - 0.5, 0.5, 1.5 and the max poorness occurs on segment "-1.5 -0.5" or "0.5 1.5". The poorness value (answer) equals to 2 in this case.


題目大意:n個數字,每個數字可以加上一個實數x,現在要使得操作完後的數列的連續和的最大值最小,求x


題目分析:最大最小顯然二分,可是二分什麼?可以發現對於原數列的連續和最大要麼是正連續和最大,要麼是連續負數的絕對值最大,顯然如果是最大正連續和大於最大負連續和的絕對值,說明x偏小,可以增大x的值,使得正值變小,負值的絕對值變大,二分邊界顯然是-10000到10000,注意這裡的精度很奇妙,1e-10 wa了,1e-15 T了, 1e-12 AC

#include <cstdio>
int const MAX = 2e5 + 5;
double const EPS = 1e-12;
int a[MAX];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    double l = -10000, r = 10000;
    double cur1, ma, cur2, mi, mid;
    while(r - l > EPS)
    {
        cur1 = cur2 = ma = mi = 0;
        mid = (l + r) / 2;
        for(int i = 1; i <= n; i++)
        {
            cur1 += a[i] - mid;
            if(cur1 < 0)
                cur1 = 0;
            if(cur1 > ma)
                ma = cur1;
            cur2 += a[i] - mid;
            if(cur2 > 0)
                cur2 = 0;
            if(cur2 < mi)
                mi = cur2;
        }
        if(ma > -mi)
            l = mid;
        else
            r = mid;
    }
    printf("%.10f\n", ma);
}


相關文章