Codeforces Round #186 (Div. 2) (ABCDE题解)

来源:互联网 发布:js跨域是 编辑:程序博客网 时间:2024/05/02 13:59

比赛链接:http://codeforces.com/contest/313



A. Ilya and Bank Account
time limit per test:2 seconds
memory limit per test:256 megabytes

Ilya is a very clever lion, he lives in an unusual city ZooVille. In this city all the animals have their rights and obligations. Moreover, they even have their own bank accounts. The state of a bank account is an integer. The state of a bank account can be a negative number. This means that the owner of the account owes the bank money.

Ilya the Lion has recently had a birthday, so he got a lot of gifts. One of them (the gift of the main ZooVille bank) is the opportunity to delete the last digit or the digit before last from the state of his bank account no more than once. For example, if the state of Ilya's bank account is -123, then Ilya can delete the last digit and get his account balance equal to -12, also he can remove its digit before last and get the account balance equal to -13. Of course, Ilya is permitted not to use the opportunity to delete a digit from the balance.

Ilya is not very good at math, and that's why he asks you to help him maximize his bank account. Find the maximum state of the bank account that can be obtained using the bank's gift.

Input

The single line contains integer n (10 ≤ |n| ≤ 109) — the state of Ilya's bank account.

Output

In a single line print an integer — the maximum state of the bank account that Ilya can get.

Sample test(s)
Input
2230
Output
2230
Input
-10
Output
0
Input
-100003
Output
-10000
Note

In the first test sample Ilya doesn't profit from using the present.

In the second test sample you can delete digit 1 and get the state of the account equal to 0.


题目大意:一个数字,可以删掉最后一个数字或者倒数第二个数字,也可以不删,问操作完的最大值


题目分析:正数直接输出,负数两种删法比个大小

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;int main(){    int n;    scanf("%d", &n);    if(n >= 0)        printf("%d\n", n);    else    {        n = -n;        if(n < 10)            printf("0\n");        else        {            int nn = n;            int tmp = n / 100;            int a = n % 10;            int b = (nn / 10) % 10;            printf("%d\n", max(-(tmp * 10 + a), -(tmp * 10 + b)));        }    }}


B. Ilya and Queries
time limit per test:2 seconds
memory limit per test:256 megabytes

Ilya the Lion wants to help all his friends with passing exams. They need to solve the following problem to pass the IT exam.

You've got string s = s1s2...sn (n is the length of the string), consisting only of characters "." and "#" andm queries. Each query is described by a pair of integersli, ri(1 ≤ li < ri ≤ n). The answer to the queryli, ri is the number of such integersi(li ≤ i < ri), thatsi = si + 1.

Ilya the Lion wants to help his friends but is there anyone to help him? Help Ilya, solve the problem.

Input

The first line contains string s of length n (2 ≤ n ≤ 105). It is guaranteed that the given string only consists of characters "." and "#".

The next line contains integer m (1 ≤ m ≤ 105) — the number of queries. Each of the nextm lines contains the description of the corresponding query. Thei-th line contains integers li, ri(1 ≤ li < ri ≤ n).

Output

Print m integers — the answers to the queries in the order in which they are given in the input.

Sample test(s)
Input
......43 42 31 62 6
Output
1154
Input
#..###51 35 61 53 63 4
Output
11220


题目大意:求[l,r]中有多少个相邻的位置字符相等


题目分析:记录[1,i]中多有少个,直接减

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int const MAX = 1e5 + 5;char s[MAX];int cnt[MAX];int main(){    scanf("%s", s + 1);    int len = strlen(s + 1);    for(int i = 1; i <= len; i++)    {        if(s[i] == s[i - 1])            cnt[i] = cnt[i - 1] + 1;        else            cnt[i] = cnt[i - 1];    }    int m;    scanf("%d", &m);    while(m --)    {        int l, r;        scanf("%d %d", &l, &r);        printf("%d\n", cnt[r] - cnt[l]);    }}


C. Ilya and Matrix
time limit per test:1 second
memory limit per test:256 megabytes

Ilya is a very good-natured lion. He likes maths. Of all mathematical objects, his favourite one is matrices. Now he's faced a complicated matrix problem he needs to solve.

He's got a square 2n × 2n-sized matrix and4n integers. You need to arrange all these numbers in the matrix (put each number in a single individual cell) so that thebeauty of the resulting matrix with numbers is maximum.

The beauty of a2n × 2n-sized matrix is an integer, obtained by the following algorithm:

  1. Find the maximum element in the matrix. Let's denote it asm.
  2. If n = 0, then the beauty of the matrix equalsm. Otherwise, a matrix can be split into 4 non-intersecting2n - 1 × 2n - 1-sized submatrices, then the beauty of the matrix equals the sum of numberm and other four beauties of the described submatrices.

As you can see, the algorithm is recursive.

Help Ilya, solve the problem and print the resulting maximum beauty of the matrix.

Input

The first line contains integer 4n (1 ≤ 4n ≤ 2·106). The next line contains4n integersai(1 ≤ ai ≤ 109) — the numbers you need to arrange in the2n × 2n-sized matrix.

Output

On a single line print the maximum value of the beauty of the described matrix.

Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use thecin,cout streams or the%I64d specifier.

Sample test(s)
Input
113
Output
13
Input
41 2 3 4
Output
14
Note

Consider the second sample. You need to arrange the numbers in the matrix as follows:

1 23 4

Then the beauty of the matrix will equal: 4 + 1 + 2 + 3 + 4 = 14.


题目大意:给4^n个数,填到一个2^n * 2^n的矩阵里,要求美丽值最大,一个矩阵的美丽值等于每2^i * 2^i个子矩阵中的最大值


题目分析:从大到小排序,计算前缀和,每次除4,表示前4^n大的和,前4^n-1大的和。。。前4大的和,类加即可,这题好像卡cin,cout,恶心。。。

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#define ll long longusing namespace std;ll a[1 << 21]; bool cmp(ll p, ll q){    return p > q;}int main(){    ll n, ans = 0;    scanf("%I64d", &n);    for(int i = 1; i <= n; i++)        scanf("%I64d", &a[i]);    sort(a + 1, a + n + 1, cmp);    for(int i = 1; i <= n; i++)        a[i] += a[i - 1];    while(n)    {        ans += a[n],        n /= 4;    }    printf("%I64d\n", ans);}


D. Ilya and Roads
time limit per test:3 seconds
memory limit per test:256 megabytes

Everything is great about Ilya's city, except the roads. The thing is, the only ZooVille road is represented asn holes in a row. We will consider the holes numbered from 1 ton, from left to right.

Ilya is really keep on helping his city. So, he wants to fix at leastk holes (perharps he can fix more) on a single ZooVille road.

The city has m building companies, thei-th company needsci money units to fix a road segment containing holes with numbers of at leastli and at mostri. The companies in ZooVille are very greedy, so, if they fix a segment containing some already fixed holes, they do not decrease the price for fixing the segment.

Determine the minimum money Ilya will need to fix at leastk holes.

Input

The first line contains three integers n, m, k (1 ≤ n ≤ 300, 1 ≤ m ≤ 105, 1 ≤ k ≤ n). The nextm lines contain the companies' description. Thei-th line contains three integers li, ri, ci(1 ≤ li ≤ ri ≤ n, 1 ≤ ci ≤ 109).

Output

Print a single integer — the minimum money Ilya needs to fix at leastk holes.

If it is impossible to fix at least k holes, print -1.

Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use thecin,cout streams or the%I64d specifier.

Sample test(s)
Input
10 4 67 9 116 9 137 7 73 5 6
Output
17
Input
10 7 13 4 158 9 85 6 89 10 61 4 21 4 108 10 13
Output
2
Input
10 1 95 10 14
Output
-1

题目大意:n个洞,m个区间,每个公司只能修补区间[li, ri]的洞并且需要花费ci,现在问至少修k个洞的最小花费,注意同一个洞多次被修的话,花费要累加


题目分析:n那么小,赤果果的区间dp,dp[i][j]表示前i个洞修了j个的最小花费,p[i][j]表示从第i个洞修到第j个洞的最小花费,先预处理p[i][j],直接在输入的时候算一下就好,转移方程:dp[i][j] = min(dp[i - 1][j],dp[i - k][j - k] + p[i - k + 1][i] (1 <= k <= j))

#include <cstdio>#include <cstring>#include <algorithm>#define ll long longusing namespace std;ll const INF = 1ll << 40;int const MAX = 305;ll dp[MAX][MAX], p[MAX][MAX];int main(){    int n, m, k;    scanf("%d %d %d", &n, &m, &k);    for(int i = 0; i <= n; i++)        for(int j = i; j <= n; j++)            dp[i][j] = p[i][j] = INF;    while(m --)    {        int l, r, c;        scanf("%d %d %d", &l, &r, &c);        for(int i = l; i <= r; i++)            p[l][i] = min(p[l][i], (ll)c);    }    dp[0][0] = 0;    for(int i = 1; i <= n; i++)    {        for(int j = 0; j <= i; j++)        {            dp[i][j] = dp[i - 1][j];            for(int k = 1; k <= j; k++)                dp[i][j] = min(dp[i][j], dp[i - k][j - k] + p[i - k + 1][i]);        }    }    if(dp[n][k] == INF)        printf("-1\n");    else        printf("%I64d\n", dp[n][k]);}


E. Ilya and Two Numbers
time limit per test:2 seconds
memory limit per test:256 megabytes

Ilya has recently taken up archaeology. He's recently found two numbers, written in them-based notation. Each of the found numbers consisted of exactlyn digits. Ilya immediately started looking for information about those numbers. He learned that the numbers are part of a cyphered code and the one who can decypher it can get the greatest treasure.

After considerable research Ilya understood that to decypher the code, he should do the following:

  • Rearrange digits in the first number in some manner. Similarly, rearrange digits in the second number in some manner. As a result of this operation, the numbers can get leading zeroes.
  • Add numbers, digit by digit, modulo m. In other words, we need to get the third number of length n, each digit of the number is the sum of the respective numbers of the found numbers. For example, suppose there are two numbers recorded in the ternary notation, 001210 and 012111, then if you add them to each other digit by digit modulo 3, you will get number 010021.
  • The key to the code is the maximum possible number that can be obtained in the previous step.

Help Ilya, find the key to the code.

Input

The first line contains two integers n, m (1 ≤ n, m ≤ 105, m > 1). The second line contains the first found number, the third line contains the second found number.

The numbers are recorded as a sequence of digits in them-based notation. Each digit is an integer from 0 tom - 1. The digits in the line are written in the order from the most significant digits to the least significant ones.

The given numbers can contain leading zeroes.

Output

Print n m-base digits. The resulting third number written in the m-based notation. Print the digits in the order from the most significant digits to the least significant ones.

Sample test(s)
Input
4 75 4 3 25 6 5 4
Output
6 4 2 1 
Input
5 52 4 4 1 31 0 1 2 4
Output
4 4 4 3 2 

题目大意:给两排n个数,每排可以任意排序,现在求两排数对m的无进位加法的最大值


题目分析:在输入的时候计数,每一排的各个数字出现了多少次,然后i从0到m-1枚举,显然对于一个i,我要去找m - i - 1和它相加,如果没有就找比m - i - 1小但尽可能大的相加,这里可以用栈维护第一排,队列维护第二排,其实相当于维护一个单调递增栈和单调递增队列,若第一排的i在第二排找完可加的数后,第二排的对应数还有剩余,则将其减去m放入队列,最后直接将队列和栈中的元素相加,因为它们都是单调的,且和都小于m,所以可以直接加,最好是在纸上画画,很难描述清楚

#include <cstdio>#include <cstring>#include <algorithm>#include <stack>#include <queue>using namespace std;int const MAX = 100005;int a[MAX], b[MAX], ans[MAX];stack <int> s;queue <int> q;int main(){    int n, m, t, cnt = 0;    scanf("%d %d", &n, &m);    for(int i = 0; i < n; i++)    {        scanf("%d", &t);        a[t] ++;    }    for(int i = 0; i < n; i++)    {        scanf("%d", &t);        b[t] ++;    }    for(int i = 0; i < m; i++)    {        while(a[i])        {            s.push(i);            a[i] --;        }        int j = m - i - 1;        while(b[j])        {            if(!s.empty())            {                ans[cnt ++] = j + s.top();                s.pop();            }            else                 q.push(j - m);            b[j] --;        }    }    while(!s.empty())    {        ans[cnt ++] = s.top() + q.front();        s.pop();        q.pop();    }    sort(ans, ans + cnt);    for(int i = n - 1; i > 0; i--)        printf("%d ", ans[i]);    printf("%d\n", ans[0]);}




0 0
原创粉丝点击