Codeforces Round #643 (Div. 2)A-E个人题解

Codeforces Round #643 Div. 2A-E个人题解

  • [A.Sequence with Digits](https://codeforces.com/contest/1355/problem/A)
    • 题面
    • 水题
    • AC代码
  • [B. Young Explorers](https://codeforces.com/contest/1355/problem/B)
    • 题面
    • 桶+贪心
    • AC代码
  • [C. Count Triangles](https://codeforces.com/contest/1355/problem/C)
    • 题面
    • 数学
    • AC代码
  • [D. Game With Array](https://codeforces.com/contest/1355/problem/D)
    • 题面
    • 思维构造
    • AC代码
  • [E. Restorer Distance](https://codeforces.com/contest/1355/problem/E)
    • 题面
    • 题面
    • AC代码

A.Sequence with Digits

题面

Let’s define the following recurrence:
a n + 1 = a n + m i n D i g i t ( a n ) ⋅ m a x D i g i t ( a n ) . a_{n+1} = a_{n} + minDigit(a_{n}) \cdot maxDigit(a_{n}). an+1=an+minDigit(an)maxDigit(an).
Here m i n D i g i t ( x ) minDigit(x) minDigit(x) and m a x D i g i t ( x ) maxDigit(x) maxDigit(x) are the minimal and maximal digits in the decimal representation of x x x without leading zeroes. For examples refer to notes.

Your task is calculate a K a_K aK for given a 1 a_1 a1 and K . K. K.

Input
The first line contains one integer t ( 1 ≤ t ≤ 1000 ) t (1≤t≤1000) t(1t1000) — the number of independent test cases.

Each test case consists of a single line containing two integers a1 and K ( 1 ≤ a 1 ≤ 1 0 18 , 1 ≤ K ≤ 1 0 16 1≤a_1≤10^{18}, 1≤K≤10^{16} 1a11018,1K1016) separated by a space.

Output
For each test case print one integer aK on a separate line.

水题

a n + 1 = a n + m i n D i g i t ( a n ) ⋅ m a x D i g i t ( a n ) . a_{n+1} = a_{n} + minDigit(a_{n}) \cdot maxDigit(a_{n}). an+1=an+minDigit(an)maxDigit(an).
m i n D i g i t ( x ) minDigit(x) minDigit(x) m a x D i g i t ( x ) maxDigit(x) maxDigit(x)表示该数十进制下的最小和最大数位
给出 a 1 a_1 a1,求 a k a_k ak
1 ≤ K ≤ 1 0 16 1≤K≤10^{16} 1K1016,看起来k很大,实际上一旦有一位是0,就停止了。跑了几个随机数也确实如此,具体证明表示不懂,莽一下就过了。

AC代码

ll getnxt(ll x) {
    ll mini = 10, maxx = -1;
    ll res = x;
    while (x) {
        mini = min(mini, x % 10);
        maxx = max(maxx, x % 10);
        x /= 10;
    }
    return res + mini * maxx;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int T;
    cin >> T;
    while (T--) {
        ll a, k;
        cin>>a>>k;
        k--;
        while (k--) {
            ll nxt = getnxt(a);
            if (a == nxt) break;
            a = nxt;
        }
        cout << a << endl;
    }
    return 0;
}

B. Young Explorers

题面

Young wilderness explorers set off to their first expedition led by senior explorer Russell. Explorers went into a forest, set up a camp and decided to split into groups to explore as much interesting locations as possible. Russell was trying to form groups, but ran into some difficulties…

Most of the young explorers are inexperienced, and sending them alone would be a mistake. Even Russell himself became senior explorer not long ago. Each of young explorers has a positive integer parameter e i e_i ei — his inexperience. Russell decided that an explorer with inexperience e e e can only join the group of e e e or more people.

Now Russell needs to figure out how many groups he can organize. It’s not necessary to include every explorer in one of the groups: some can stay in the camp. Russell is worried about this expedition, so he asked you to help him.

Input
The first line contains the number of independent test cases T ( 1 ≤ T ≤ 2 ⋅ 1 0 5 ) T(1≤T≤2⋅10^5) T(1T2105). Next 2T lines contain description of test cases.

The first line of description of each test case contains the number of young explorers N ( 1 ≤ N ≤ 2 ⋅ 1 0 5 1≤N≤2⋅10^5 1N2105).

The second line contains N N N integers e 1 , e 2 , … , e N ( 1 ≤ e i ≤ N ) e_1,e_2,…,e_N (1≤e_i≤N) e1,e2,,eN(1eiN), where ei is the inexperience of the i-th explorer.

It’s guaranteed that sum of all N N N doesn’t exceed 3 ⋅ 1 0 5 3⋅10^5 3105.

Output
Print T numbers, each number on a separate line.

In i-th line print the maximum number of groups Russell can form in i-th test case.

桶+贪心

题意就是有n个人,每个人有一个 e i e_i ei,组成一个小组的条件是小组里所有人的 e i ≤ e_i\le ei小组人数。
求能组成最大小组数。
拿桶装一下,可以组就组,小的剩下的肯定可以拿给大的,贪之。

AC代码

        int n;
        cin >> n;
        vector<int> cnt(n + 1);
        for (int i = 0, x; i < n; ++i) {
            cin >> x;
            cnt[x]++;
        }
        int ans = 0;
        for (int i = 1, remain = 0; i <= n; ++i) {
            ans += (cnt[i] + remain) / i;
            remain = (cnt[i] + remain) % i;
        }
        cout << ans << endl;

C. Count Triangles

题面

Like any unknown mathematician, Yuri has favourite numbers: A , B , C , a n d D A, B, C, and D A,B,C,andD, where A ≤ B ≤ C ≤ D A≤B≤C≤D ABCD. Yuri also likes triangles and once he thought: how many non-degenerate triangles with integer sides x , y , a n d z x, y, and z x,y,andz exist, such that A ≤ x ≤ B ≤ y ≤ C ≤ z ≤ D A≤x≤B≤y≤C≤z≤D AxByCzD holds?

Yuri is preparing problems for a new contest now, so he is very busy. That’s why he asked you to calculate the number of triangles with described property.

The triangle is called non-degenerate if and only if its vertices are not collinear.

Input
The first line contains four integers: A , B , C a n d D ( 1 ≤ A ≤ B ≤ C ≤ D ≤ 5 ⋅ 1 0 5 ) A, B, C and D (1≤A≤B≤C≤D≤5⋅10^5) A,B,CandD(1ABCD5105) — Yuri’s favourite numbers.

Output
Print the number of non-degenerate triangles with integer sides x , y , a n d z x, y, and z x,y,andz such that the inequality A ≤ x ≤ B ≤ y ≤ C ≤ z ≤ D A≤x≤B≤y≤C≤z≤D AxByCzD holds.

数学

题意就是给出 A , B , C , D A,B,C,D A,B,C,D四个数,其中 A ≤ B ≤ C ≤ D A≤B≤C≤D ABCD.
求有多少 x , y , z 满 足 A ≤ x ≤ B ≤ y ≤ C ≤ z ≤ D x,y,z满足A≤x≤B≤y≤C≤z≤D x,y,zAxByCzD且x,y,z可以构成一个三角形。
暴力肯定是 N 3 N^3 N3,肯定不行。
其实当我们得知x,y时,z的范围就确定了。所以不用遍历z。
但这是 N 2 N^2 N2,依旧不行。
显然只能遍历一维,我选择遍历x,因为z是 ≥ C \ge C C的所以要使得满足三角形的最小y就是 C + 1 − x C+1-x C+1x,再加上y本身的限制条件,于是有满足三角形的最小 y = m a x ( b , C + 1 − x ) y=max(b,C+1-x) y=max(b,C+1x)
得到了x和与之对应的最小的y。
则此时有x + y - C这么多个z可以组成三角形,注意y还可以递增到C,每次一递增,就会多出1个三角形(z的取值变大1)。
昭然若揭,等差为1的等差数列求和。
是不是以为这样就可以了,错了。还有一种情况是x+y已经大于D了,很显然此时y在增大也不会再递增。
拎出来特判一下,遂AC。

AC代码

ll a, b, c, d;
    cin >> a >> b >> c >> d;
    ll ans = 0;
    for (ll x = a; x <= b; ++x) {
        ll y = max(b, c + 1 - x);
        if (x + y > d) {
            ans += (d - c + 1) * (c - y + 1);
        } else {
            ll a1 = x + y - c, n = min(d - x - y + 1, c - y + 1);
            ans += n * a1 + n * (n - 1) / 2;
            if (d - x < c) ans += (d - c + 1) * (c + x - d);
        }
    }
    cout << ans << endl;

D. Game With Array

题面

Petya and Vasya are competing with each other in a new interesting game as they always do.

At the beginning of the game Petya has to come up with an array of N N N positive integers. Sum of all elements in his array should be equal to S S S. Then Petya has to select an integer K K K such that 0 ≤ K ≤ S 0≤K≤S 0KS.

In order to win, Vasya has to find a non-empty subarray in Petya’s array such that the sum of all selected elements equals to either K K K or S − K S−K SK. Otherwise Vasya loses.

You are given integers N and S. You should determine if Petya can win, considering Vasya plays optimally. If Petya can win, help him to do that.

Input
The first line contains two integers N and S ( 1 ≤ N ≤ S ≤ 1 0 6 1≤N≤S≤10^6 1NS106) — the required length of the array and the required sum of its elements.

Output
If Petya can win, print “YES” (without quotes) in the first line. Then print Petya’s array in the second line. The array should contain N positive integers with sum equal to S. In the third line print K. If there are many correct answers, you can print any of them.

If Petya can’t win, print “NO” (without quotes).

You can print each letter in any register (lowercase or uppercase).

思维构造

给出一个数组长度 N N N,数组总和 S S S
你需要构造一个符合上述条件的数组和一个满足 0 ≤ K ≤ S 0≤K≤S 0KS.的 K K K
使得没有子数组/子段的和 ≠ \ne =K也 ≠ \ne =S-K
样例给的都是K都是S/2,诱导了我。
实际上K是1,数组元素均>1即可。

AC代码

	int n, s;
    cin >> n >> s;
    vector<int> ans;
    while (n > 1) {
        ans.emplace_back(2);
        s -= 2;
        n--;
    }
    ans.emplace_back(s);
    if (ans.back() > 1) {
        cout << "YES" << endl;
        for (auto &it : ans) cout << it << ' ';
        cout << '\n' << 1 << endl;
        return 0;
    }
    cout << "NO" << endl;

E. Restorer Distance

题面

You have to restore the wall. The wall consists of N N N pillars of bricks, the height of the i i i-th pillar is initially equal to h i h_i hi, the height is measured in number of bricks. After the restoration all the N N Npillars should have equal heights.

You are allowed the following operations:

  • put a brick on top of one pillar, the cost of this operation is A A A;
  • remove a brick from the top of one non-empty pillar, the cost of this operation is R R R;
  • move a brick from the top of one non-empty pillar to the top of another pillar, the cost of this operation is M M M.

You cannot create additional pillars or ignore some of pre-existing pillars even if their height becomes 0 0 0.

What is the minimal total cost of restoration, in other words, what is the minimal total cost to make all the pillars of equal height?

Input

The first line of input contains four integers N , A , R , M ( 1 ≤ N ≤ 1 0 5 , 0 ≤ A , R , M ≤ 1 0 4 ) N, A, R, M (1≤N≤10^5, 0≤A,R,M≤10^4) N,A,R,M(1N105,0A,R,M104) — the number of pillars and the costs of operations.

The second line contains N N N integers h I ( 0 ≤ h i ≤ 1 0 9 ) h_I (0≤h_i≤10^9) hI(0hi109) — initial heights of pillars.

Output

Print one integer — the minimal cost of restoration.

题面

给出n个长度为 h i h_i hi个砖累成的柱子,花费A可以放一块砖到任意柱子上,花费R可以取走任意柱子上的一块砖,花费M可以把任意柱子的一块砖放到任意柱子上。注意,即使柱子的高度为0,也不能当他没有柱子。求所有柱子一样高的最小花费。
敏锐地觉察(猜)到这是一个三分,当远离最小花费的高度时,花费只会递增。
于是三分高度去做,每次贪心的操作即可。

AC代码

ll judge(int x, vector<int> &h, int a, int r, int m) {
    ll ans = 0;
    if (a + r <= m) {
        for (int i = 0; i < h.size(); ++i) {
            if (h[i] < x) ans += 1ll * (x - h[i]) * a;
            if (h[i] > x) ans += 1ll * (h[i] - x) * r;
        }
        return ans;
    } else {
        ll L = 0, R = 0;
        for (int i = 0; i < h.size(); ++i) {
            if (h[i] < x) L += (x - h[i]);
            if (h[i] > x) R += (h[i] - x);
        }
        if (L < R) return L * m + (R - L) * r;
        return R * m + (L - R) * a;
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n, a, R, m;
    cin >> n >> a >> R >> m;
    vector<int> h(n);
    for (auto &it : h) cin >> it;
    int l = 0, r = 1e9 + 1;
    while (l + 1 < r) {
        int lm = (l + r) >> 1, rm = (lm + r) >> 1;
        if (judge(lm, h, a, R, m) > judge(rm, h, a, R, m))
            l = lm;
        else
            r = rm;
    }
    cout << judge(r, h, a, R, m) << endl;
    return 0;
}

你可能感兴趣的:(codeforces,算法)