Codeforces Round #802(Div. 2)A~D

Codeforces Round #802(Div. 2)A~D

Problem - A - Codeforces

You are given a table a of size n×m. We will consider the table rows numbered from top to bottom from 1 to n, and the columns numbered from left to right from 1 to m. We will denote a cell that is in the i-th row and in the j-th column as (i,j). In the cell (i,j) there is written a number (i−1)⋅m+j, that is aij=(i−1)⋅m+j.

A turtle initially stands in the cell (1,1) and it wants to come to the cell (n,m). From the cell (i,j) it can in one step go to one of the cells (i+1,j) or (i,j+1), if it exists. A path is a sequence of cells in which for every two adjacent in the sequence cells the following satisfies: the turtle can reach from the first cell to the second cell in one step. A cost of a path is the sum of numbers that are written in the cells of the path.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pAemaVxs-1656142330529)(https://espresso.codeforces.com/9857613b5dbdfcc9e89d5add1183537c52368425.png)]

For example, with n=2 and m=3 the table will look as shown above. The turtle can take the following path: (1,1)→(1,2)→(1,3)→(2,3). The cost of such way is equal to a11+a12+a13+a23=12. On the other hand, the paths (1,1)→(1,2)→(2,2)→(2,1) and (1,1)→(1,3) are incorrect, because in the first path the turtle can’t make a step (2,2)→(2,1), and in the second path it can’t make a step (1,1)→(1,3).

You are asked to tell the turtle a minimal possible cost of a path from the cell (1,1) to the cell (n,m). Please note that the cells (1,1) and (n,m) are a part of the way.

Input

The first line contains a single integer t (1≤t≤1000) — the number of test cases. The description of test cases follows.

A single line of each test case contains two integers n and m (1≤n,m≤104) — the number of rows and columns of the table a respectively.

Output

For each test case output a single integer — a minimal possible cost of a path from the cell (1,1) to the cell (n,m).

Example
input
7
1 1
2 3
3 2
7 1
1 10
5 5
10000 10000
output
1
12
13
28
55
85
500099995000

问题解析

题目是说给你一个n*m的矩阵,每次只能向右或下走,问你从左上走到右下的最低代价是多少。

最低的代价就是先向右走在往下走,这样代价就是一个首项为1公差为1的等差数列前m项和加上首项为m,公差为m的等差数列前n项和减去一个m。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50;

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        int n, m;
        cin >> n >> m;
        cout << (m * (m + 1) / 2) + ((n * m * n + m * n) / 2) - m << endl;
    }
    return 0;
}

Problem - B - Codeforces

During a daily walk Alina noticed a long number written on the ground. Now Alina wants to find some positive number of same length without leading zeroes, such that the sum of these two numbers is a palindrome.

Recall that a number is called a palindrome, if it reads the same right to left and left to right. For example, numbers 121,66,98989121,66,98989 are palindromes, and 103,239,1241103,239,1241 are not palindromes.

Alina understands that a valid number always exist. Help her find one!

Input

The first line of input data contains an integer tt (1≤t≤1001≤t≤100) — the number of test cases. Next, descriptions of tt test cases follow.

The first line of each test case contains a single integer nn (2≤n≤1000002≤n≤100000) — the length of the number that is written on the ground.

The second line of contains the positive nn-digit integer without leading zeroes — the number itself.

It is guaranteed that the sum of the values nn over all test cases does not exceed 100000100000.

Output

For each of tt test cases print an answer — a positive nn-digit integer without leading zeros, such that the sum of the input integer and this number is a palindrome.

We can show that at least one number satisfying the constraints exists. If there are multiple solutions, you can output any of them.

Example
input
3
2
99
4
1023
3
385
output
32
8646
604

问题解析

题目是说给你一个长度为n的数,让你找一个长度和它相等的数,要这两个数相加是一个回文数。

那我们直接用一个长度为n的全是9的数减去他给的数即可。因为不能有前导零,如果第一个数是9,那我们就用一个长度为n+1全是1的数给减去它给的数即可。一个高精度减法。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50;

vector<int> sub(vector<int>& A, vector<int>& B)
{
    vector<int>C;
    int t = 0;
    for (int i = 0; i < A.size(); i++)
    {
        t = A[i] - t;
        if (i < B.size())t -= B[i];
        C.push_back((t + 10) % 10);
        if (t < 0)t = 1;
        else t = 0;
    }
    while (C.size() > 1 && !C.back())
        C.pop_back();
    return C;
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        string s;
        int n;
        cin >> n >> s;
        vector<int>a(n);
        for (int i = 0; i < n; i++)
        {
            a[i] = s[i] - '0';
        }
        
        vector<int>b(n,9);
        if (a[0] == 9)
        {
            b.assign(n + 1, 1);
        }
        reverse(a.begin(), a.end());
        auto c = sub(b, a);
        for (int i = c.size() - 1; i >= 0; i--)cout << c[i];
        cout << endl;
    }
    return 0;
}

Problem - C - Codeforces

Little Leon lives in the forest. He has recently noticed that some trees near his favourite path are withering, while the other ones are overhydrated so he decided to learn how to control the level of the soil moisture to save the trees.

There are n trees growing near the path, the current levels of moisture of each tree are denoted by the array a1,a2,…,an. Leon has learned three abilities which will help him to dry and water the soil.

Choose a position i and decrease the level of moisture of the trees 1,2,…,i by 1.
Choose a position i and decrease the level of moisture of the trees i,i+1,…,n by 1.
Increase the level of moisture of all trees by 1.
Leon wants to know the minimum number of actions he needs to perform to make the moisture of each tree equal to 0.

Input

The first line contains a single integer t (1≤t≤2⋅104) — the number of test cases. The description of t test cases follows.

The first line of each test case contains a single integer n (1≤n≤200000).

The second line of each test case contains n integers a1,a2,…,an (−109≤ai≤109) — the initial levels of trees moisture.

It is guaranteed that the sum of n over all test cases doesn’t exceed 200000.

Output

For each test case output a single integer — the minimum number of actions. It can be shown that the answer exists.

Example
input
4
3
-2 -2 -2
3
10 4 7
4
4 -4 4 -4
5
1 -2 3 -4 5
output
2
13
36
33

问题解析

题目说给你一个数组,你可以把前面i个元素都-1,或者后面i个元素都-1,或者全体+1,问你要多少步才能使得全部都是0.

看到全体一样,先想差分数组,只要把差分数组全变成0,那就是全体都是0了。然后把这三个操作转化一下,就是:

第一个元素-1,第i个元素+1;

第i个元素-1;

第一个元素+1;

那么我们可以从尾到头遍历差分数组,根据它的正负情况看什么操作能把他全部变成0,途中记录下使用的次数就行。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50;

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        vector <int> a(n), b(n);
        for (int i = 0; i < n; i++)cin >> a[i];
        b[0] = a[0];
        for (int i = 1; i < n; i++)
        {
            b[i] = a[i] - a[i - 1];
        }
        int res = 0;
        for (int i = n - 1; i > 0; i--)
        {
            if (b[i] > 0)
            {
                res += b[i];
            }
            else
            {
                res += abs(b[i]);
                b[0] += b[i];
            }
        }
        cout << res + abs(b[0]) << endl;
    }
    return 0;
}

Problem - D - Codeforces

Recently in Divanovo, a huge river locks system was built. There are now n locks, the i-th of them has the volume of vi liters, so that it can contain any amount of water between 0 and vi liters. Each lock has a pipe attached to it. When the pipe is open, 1 liter of water enters the lock every second.

The locks system is built in a way to immediately transfer all water exceeding the volume of the lock i to the lock i+1. If the lock i+1 is also full, water will be transferred further. Water exceeding the volume of the last lock pours out to the river.

img

Note that the volume of the i-th lock may be greater than the volume of the i+1-th lock.

To make all locks work, you need to completely fill each one of them. The mayor of Divanovo is interested in q independent queries. For each query, suppose that initially all locks are empty and all pipes are closed. Then, some pipes are opened simultaneously. For the j-th query the mayor asks you to calculate the minimum number of pipes to open so that all locks are filled no later than after tj seconds.

Please help the mayor to solve this tricky problem and answer his queries.

Input

The first lines contains one integer n (1≤n≤200000) — the number of locks.

The second lines contains n integers v1,v2,…,vn (1≤vi≤109)) — volumes of the locks.

The third line contains one integer q (1≤q≤200000) — the number of queries.

Each of the next q lines contains one integer tj (1≤tj≤109) — the number of seconds you have to fill all the locks in the query j.

Output

Print q integers. The j-th of them should be equal to the minimum number of pipes to turn on so that after tj seconds all of the locks are filled. If it is impossible to fill all of the locks in given time, print −1.

Examples
input
5
4 1 5 4 1
6
1
6
2
3
4
5
output
-1
3
-1
-1
4
3

问题解析

题目说给你n个容器,每个容器容积为a[i],它们每个头上都有个水龙头,开启后1秒可以加一单位的水到下面的容器,如果下面的容器装满了,水会进入下个容器,然后有m个题问,每次给你个时间,问你能不能在规定时间内装满所有的容器,如果可以,最少用几个水龙头,如果不能就输出-1。

可以知道,水龙头尽量开前面的最好,哪怕当前装满了也可以加到后面去,那么我们可以先假设一下每个水龙头都开,然后计算一下灌满每个容器至少要多少时间,如果提问给的时间少于这个时间,那就肯定是-1。然后我们可以二分答案求一下开的水龙头数量,要灌满全部的容器,那么水龙头在他给的时间内要能流出(a[0]+a[1]+……a[n-1])单位的水,我们只要算开多少水龙头能满足它即可。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50;

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n, m, mn = -1, res = 0;
    cin >> n;
    vector <int> a(n);
    for (int i = 0; i < n; i++)cin >> a[i];
    for (int i = 0; i < n; i++)
    {
        res += a[i];
        int x = res / (i+1);
        if (res % (i+1) != 0)x++;
        mn = max(mn, x);
    }
    cin >> m;
    while (m--)
    {
        int x;
        cin >> x;
 
        if (x < mn)
        {
            cout << -1 << endl;
            continue;
        }
        int l = 0, r = n + 1;
        while (l < r)
        {
            int mid = (l + r) / 2;
            if (x * mid >= res)r = mid;
            else l = mid + 1;
        }
        if (l == n + 1)cout << -1 << endl;
        else cout << l << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值