Codeforces Round #538 (Div. 2)

要不是杰哥抬了一手这场又要掉分……菜是原罪

A. Got Any Grapes?

Description:

The Duck songFor simplicity, we’ll assume that there are only three types of grapes: green grapes, purple grapes and black grapes.
Andrew, Dmitry and Michal are all grapes’ lovers, however their preferences of grapes are different. To make all of them happy, the following should happen:
Andrew, Dmitry and Michal should eat at least x x x, y y y and z z z grapes, respectively. Andrew has an extreme affinity for green grapes, thus he will eat green grapes and green grapes only. On the other hand, Dmitry is not a fan of black grapes — any types of grapes except black would do for him. In other words, Dmitry can eat green and purple grapes. Michal has a common taste — he enjoys grapes in general and will be pleased with any types of grapes, as long as the quantity is sufficient.Knowing that his friends are so fond of grapes, Aki decided to host a grape party with them. He has prepared a box with a a a green grapes, b b b purple grapes and c c c black grapes.
However, Aki isn’t sure if the box he prepared contains enough grapes to make everyone happy. Can you please find out whether it’s possible to distribute grapes so that everyone is happy or Aki has to buy some more grapes?
It is not required to distribute all the grapes, so it’s possible that some of them will remain unused.

Input:

uck song

Output

he first line contains three integers x x x, y y y and z z z ( 1 x , y , z 1 0 5 1 \le x, y, z \le 10^5 1x,y,z105) — the number of grapes Andrew, Dmitry and Michal want to eat.
The second line contains three integers a a a, b b b, c c c ( 1 a , b , c 1 0 5 1 \le a, b, c \le 10^5 1a,b,c105) — the number of green, purple and black grapes in the box.

Sample Input:

1 6 2
4 3 3

Sample Output:

YES

Sample Input:

5 1 1
4 3 2

Sample Output:

NO

题目链接

三个人三种颜色的物品,其中一个人只要一种颜色的物品,一个人可以要两种颜色的物品,一个人可以要任意种颜色的物品,三种物品分别有 a , b , c a,b,c a,b,c 个,三个人分别需要 x , y , z x,y,z x,y,z 个,问能否满足分配需求

模拟即可

AC代码:

#include <bits/stdc++.h>
using namespace std;

int X, Y, Z;
int A, B, C;

int main(int argc, char *argv[]) {
    scanf("%d%d%d", &X, &Y, &Z);
    scanf("%d%d%d", &A, &B, &C);
    if (A < X) {
        printf("NO\n");
        return 0;
    }
    A -= X;
    if (A + B < Y) {
        printf("NO\n");
        return 0;
    }
    if (A >= Y) A -= Y;
    else {
        Y -= A;
        A = 0;
        B -= Y;
    }
    Y = 0;
    if (A + B + C < Z) {
        printf("NO\n");
        return 0;
    }
    printf("YES\n");
    return 0;
}

B. Yet Another Array Partitioning Task

Description:

An array b b b is called to be a subarray of a a a if it forms a continuous subsequence of a a a, that is, if it is equal to a l a_l al, a l + 1 a_{l + 1} al+1, \ldots , a r a_r ar for some l , r l, r l,r.
Suppose m m m is some known constant. For any array, having m m m or more elements, let’s define it’s beauty as the sum of m m m largest elements of that array. For example:

  • For array x = [ 4 , 3 , 1 , 5 , 2 ] x = [4, 3, 1, 5, 2] x=[4,3,1,5,2] and m = 3 m = 3 m=3, the 3 3 3 largest elements of x x x are 5 5 5, 4 4 4 and 3 3 3, so the beauty of x x x is 5 + 4 + 3 = 12 5 + 4 + 3 = 12 5+4+3=12.
  • For array x = [ 10 , 10 , 10 ] x = [10, 10, 10] x=[10,10,10] and m = 2 m = 2 m=2, the beauty of x x x is 10 + 10 = 20 10 + 10 = 20 10+10=20.

You are given an array a 1 , a 2 , , a n a_1, a_2, \ldots, a_n a1,a2,,an, the value of the said constant m m m and an integer k k k. Your need to split the array a a a into exactly k k k subarrays such that:

  • Each element from a a a belongs to exactly one subarray.
  • Each subarray has at least m m m elements.
  • The sum of all beauties of k k k subarrays is maximum possible.

Input:

The first line contains three integers n n n, m m m and k k k ( 2 n 2 1 0 5 2 \le n \le 2 \cdot 10^5 2n2105, 1 m 1 \le m 1m, 2 k 2 \le k 2k, m k n m \cdot k \le n mkn) — the number of elements in a a a, the constant m m m in the definition of beauty and the number of subarrays to split to.
The second line contains n n n integers a 1 , a 2 , , a n a_1, a_2, \ldots, a_n a1,a2,,an ( 1 0 9 a i 1 0 9 -10^9 \le a_i \le 10^9 109ai109).

Output

In the first line, print the maximum possible sum of the beauties of the subarrays in the optimal partition.
In the second line, print k 1 k-1 k1 integers p 1 , p 2 , , p k 1 p_1, p_2, \ldots, p_{k-1} p1,p2,,pk1 ( 1 p 1 &lt; p 2 &lt; &lt; p k 1 &lt; n 1 \le p_1 &lt; p_2 &lt; \ldots &lt; p_{k-1} &lt; n 1p1<p2<<pk1<n) representing the partition of the array, in which:
All elements with indices from 1 1 1 to p 1 p_1 p1 belong to the first subarray. All elements with indices from p 1 + 1 p_1 + 1 p1+1 to p 2 p_2 p2 belong to the second subarray. \ldots . All elements with indices from p k 1 + 1 p_{k-1} + 1 pk1+1 to n n n belong to the last, k k k-th subarray.If there are several optimal partitions, print any of them.

Sample Input:

9 2 3
5 2 5 2 4 1 1 3 2

Sample Output:

21
3 5

Sample Input:

6 1 4
4 1 3 2 2 3

Sample Output:

12
1 3 5

Sample Input:

2 1 2
-1000000000 1000000000

Sample Output:

0
1

题目链接

一个数列在 m m m 限定下的的beauty是数列中最大的 m m m 个数之和,现给出一个数列求此数列分为 k k k 个连续子数列后每个子数列在限定 m m m 下的beauty之和最大值,并输出子序列分组情况

显然最大值应该是数列中最大的 m k mk mk 个数之和,所以按照降序排序之后取前 m k mk mk 个数即为beauty之和最大值,分组就将这 m k mk mk 个数按照原数列下标升序排序后每 m m m 个数分为一组即可

AC代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main(int argc, char *argv[]) {
    int N, M, K; scanf("%d%d%d", &N, &M, &K);
    vector<pair<ll, int> > A(N);
    for (int i = 0; i < N; ++i) {
        scanf("%lld", &A[i].first);
        A[i].second = i + 1;
    }
    sort(A.begin(), A.end());
    reverse(A.begin(), A.end());
    ll Ans = 0;
    for (int i = 0; i < M * K; ++i) Ans += A[i].first;
    printf("%lld\n", Ans);
    sort(A.begin(), A.begin() + M * K, [&](pair<ll, int> Key1, pair<ll, int> Key2) {return Key1.second < Key2.second;});
    for (int i = M - 1, k = 0; k < K - 1; i += M, ++k) printf("%d ", A[i].second);
    return 0;
}

C. Trailing Loves (or L’oeufs?)

Description:

The number “zero” is called “love” (or “l’oeuf” to be precise, literally means “egg” in French), for example when denoting the zero score in a game of tennis. Aki is fond of numbers, especially those with trailing zeros. For example, the number 9200 9200 9200 has two trailing zeros. Aki thinks the more trailing zero digits a number has, the prettier it is.
However, Aki believes, that the number of trailing zeros of a number is not static, but depends on the base (radix) it is represented in. Thus, he considers a few scenarios with some numbers and bases. And now, since the numbers he used become quite bizarre, he asks you to help him to calculate the beauty of these numbers.
Given two integers n n n and b b b (in decimal notation), your task is to calculate the number of trailing zero digits in the b b b-ary (in the base/radix of b b b) representation of n &ThinSpace; ! n\,! n! (factorial of n n n).

Input:

number “zero” is called “love” (or “l’oeuf” to be precise, literally means “egg” in French), for example when denoting the zero score in a game of tennis.

Output

he only line of the input contains two integers n n n and b b b ( 1 n 1 0 18 1 \le n \le 10^{18} 1n1018, 2 b 1 0 12 2 \le b \le 10^{12} 2b1012).

Sample Input:

6 9

Sample Output:

1

Sample Input:

38 11

Sample Output:

3

Sample Input:

5 2

Sample Output:

3

Sample Input:

5 10

Sample Output:

1

题目链接

n ! n! n! m m m 进制下末尾 0 0 0 的个数

前一段训练赛还打过原题,但是那场没有补题就……

贴一下那道题目以及题解

末尾0的个数

首先你得知道在 10 10 10 进制下 n ! n! n! 有多少个零 (就是求 5 5 5 出现的次数)
然后
假设 m m m 可以分为若干个质因子相乘
m = p 1 k 1 p 2 k 2 p 3 k 3 p 4 k 4 m = p_1^{k_1}*p_2^{k_2}*p_3^{k_3}*p_4^{k_4} m=p1k1p2k2p3k3p4k4…( p i p_i pi 质因子, k i k_i ki 质因子的次方)
那么答案就是 min(在 n ! n! n! 中每个 p i p_i pi 出现的次数 k i k_i ki );

AC代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

ll Cal(ll X, ll N) {
    ll Ans = 0;
    while(N) {
        Ans += N / X;
        N /= X;
    }
    return Ans;
}

int main() {
    ll Ans = 1e18 + 10;
    ll N, M;
    scanf("%lld %lld", &N, &M);
    for(ll i = 2; i * i <= M; i++) {
        if(M % i == 0) {
            ll Cnt = 0;
            while(M % i == 0) M /= i, Cnt++;
            Ans = min(Ans, Cal(i, N) / Cnt);
        }
    }
    if(M > 1) Ans = min(Ans, Cal(M, N));
    printf("%lld\n", Ans);
    return 0;
}

D. Flood Fill

Description:

You are given a line of n n n colored squares in a row, numbered from 1 1 1 to n n n from left to right. The i i i-th square initially has the color c i c_i ci.
Let’s say, that two squares i i i and j j j belong to the same connected component if c i = c j c_i = c_j ci=cj, and c i = c k c_i = c_k ci=ck for all k k k satisfying i &lt; k &lt; j i &lt; k &lt; j i<k<j. In other words, all squares on the segment from i i i to j j j should have the same color.
For example, the line [ 3 , 3 , 3 ] [3, 3, 3] [3,3,3] has 1 1 1 connected component, while the line [ 5 , 2 , 4 , 4 ] [5, 2, 4, 4] [5,2,4,4] has 3 3 3 connected components.
The game “flood fill” is played on the given line as follows:
At the start of the game you pick any starting square (this is not counted as a turn). Then, in each game turn, change the color of the connected component containing the starting square to any other color. Find the minimum number of turns needed for the entire line to be changed into a single color.

Input:

The first line contains a single integer n n n ( 1 n 5000 1 \le n \le 5000 1n5000) — the number of squares.
The second line contains integers c 1 , c 2 , , c n c_1, c_2, \ldots, c_n c1,c2,,cn ( 1 c i 5000 1 \le c_i \le 5000 1ci5000) — the initial colors of the squares.

Output

Print a single integer — the minimum number of the turns needed.

Sample Input:

4
5 2 2 1

Sample Output:

2

Sample Input:

8
4 5 2 2 1 3 5 5

Sample Output:

4

Sample Input:

1
4

Sample Output:

0

题目链接

一个数列中每次可以选择数字相同的连续子序列变为任意数字,求将数列中所有数字都变相同的最少操作次数

很显然的区间dp问题,但是赛时没时间写了……真的菜

显然原数列中数字相同的连续子序列不用变化,所以去重一下

之后考虑区间dp,枚举区间长度,在区间长度上继续枚举区间,状态转移就是
d p [ l ] [ r ] { <mstyle displaystyle="false" scriptlevel="0"> d p [ l + 1 ] [ r 1 ] + 1 </mstyle> <mstyle displaystyle="false" scriptlevel="0"> ( c [ l ] = = c [ r ] ) </mstyle> <mstyle displaystyle="false" scriptlevel="0"> min ( d p [ l + 1 ] [ r ] , d p [ l ] [ r 1 ] ) + 1 </mstyle> <mstyle displaystyle="false" scriptlevel="0"> ( c [ l ] c [ r ] ) </mstyle> dp[l][r] \begin{cases} dp[l+1][r-1]+1&amp;(c[l]==c[r])\\ \min(dp[l+1][r],dp[l][r-1])+1&amp;(c[l] \neq c[r]) \end{cases} dp[l][r]{dp[l+1][r1]+1min(dp[l+1][r],dp[l][r1])+1(c[l]==c[r])(c[l]̸=c[r])

AC代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn = 5e3 + 5;
const int INF = 0x3f3f3f3f;

int N;
int C[maxn];
int Dp[maxn][maxn];

int main(int argc, char *argv[]) {
    scanf("%d", &N);
    for (int i = 1; i <= N; ++i) scanf("%d", &C[i]);
    N = unique(C + 1, C + N + 1) - C - 1;
    for (int k = 1; k <= N; ++k) {
        for (int l = 0; l <= N; ++l) {
            int r = l + k;
            if (C[l] == C[r]) Dp[l][r] = Dp[l + 1][r - 1] + 1;
            else Dp[l][r] = min(Dp[l][r - 1], Dp[l + 1][r]) + 1;
        }
    }
    printf("%d\n", Dp[1][N]);
    return 0;
}

E. Arithmetic Progression

Description:

This is an interactive problem!
An arithmetic progression or arithmetic sequence is a sequence of integers such that the subtraction of element with its previous element ( x i x i 1 x_i - x_{i - 1} xixi1, where i 2 i \ge 2 i2) is constant — such difference is called a common difference of the sequence.
That is, an arithmetic progression is a sequence of form x i = x 1 + ( i 1 ) d x_i = x_1 + (i - 1) d xi=x1+(i1)d, where d d d is a common difference of the sequence.
There is a secret list of n n n integers a 1 , a 2 , , a n a_1, a_2, \ldots, a_n a1,a2,,an.
It is guaranteed that all elements a 1 , a 2 , , a n a_1, a_2, \ldots, a_n a1,a2,,an are between 0 0 0 and 1 0 9 10^9 109, inclusive.
This list is special: if sorted in increasing order, it will form an arithmetic progression with positive common difference ( d &gt; 0 d &gt; 0 d>0). For example, the list [ 14 , 24 , 9 , 19 ] [14, 24, 9, 19] [14,24,9,19] satisfies this requirement, after sorting it makes a list [ 9 , 14 , 19 , 24 ] [9, 14, 19, 24] [9,14,19,24], which can be produced as x n = 9 + 5 ( n 1 ) x_n = 9 + 5 \cdot (n - 1) xn=9+5(n1).
Also you are also given a device, which has a quite discharged battery, thus you can only use it to perform at most 60 60 60 queries of following two types:

  • Given a value i i i ( 1 i n 1 \le i \le n 1in), the device will show the value of the a i a_i ai.
  • Given a value x x x ( 0 x 1 0 9 0 \le x \le 10^9 0x109), the device will return 1 1 1 if an element with a value strictly greater than x x x exists, and it will return 0 0 0 otherwise.

Your can use this special device for at most 60 60 60 queries. Could you please find out the smallest element and the common difference of the sequence? That is, values x 1 x_1 x1 and d d d in the definition of the arithmetic progression. Note that the array a a a is not sorted.

Interaction:

actionThe interaction starts with a single integer n n n ( 2 n 1 0 6 2 \le n \le 10^6 2n106), the size of the list of integers.
Then you can make queries of two types:

  • “? i” ( 1 i n 1 \le i \le n 1in) — to get the value of a i a_i ai.
  • “> x” ( 0 x 1 0 9 0 \le x \le 10^9 0x109) — to check whether there exists an element greater than x x x

After the query read its result r r r as an integer.

  • For the first query type, the r r r satisfies 0 r 1 0 9 0 \le r \le 10^9 0r109.
  • For the second query type, the r r r is either 0 0 0 or 1 1 1.
  • In case you make more than 60 60 60 queries or violated the number range in the queries, you will get a r = 1 r = -1 r=1.
  • If you terminate after receiving the -1, you will get the “Wrong answer” verdict. Otherwise you can get an arbitrary verdict because your solution will continue to read from a closed stream.

When you find out what the smallest element x 1 x_1 x1 and common difference d d d, print

  • "! x 1 x_1 x1 d d d"

And quit after that. This query is not counted towards the 60 60 60 queries limit.
After printing any query do not forget to output end of line and flush the output. Otherwise you will get Idleness limit exceeded. To do this, use:

  • fflush(stdout) or cout.flush() in C++;
  • System.out.flush() in Java;
  • flush(output) in Pascal;
  • stdout.flush() in Python;
  • see documentation for other languages.

Hacks:

For hack, use the following format:
The first line should contain an integer n n n ( 2 n 1 0 6 2 \le n \le 10^6 2n106) — the list’s size.
The second line contains n n n integers a 1 , a 2 , , a n a_1, a_2, \ldots, a_n a1,a2,,an ( 0 a i 1 0 9 0 \le a_i \le 10^9 0ai109) — the elements of the list.
Also, after the sorting the list must form an arithmetic progression with positive common difference.

Sample Input:

4
0
1
14
24
9
19

Sample Output:

> 25
> 15
? 1
? 2
? 3
? 4
! 9 5

题目链接

一道交互题目,有一个 n n n 个数的无序等差数列,可以用两种询问询问至多 60 60 60 次,求等差数列首项和公差,两种询问分别为:

  1. ? ! 代表询问数列中第 i i i 个数的数值
  2. > x 代表询问数列中严格大于 x x x 数字的数量

交互题目无非就是二分、随机、倍增这么几种算法的考察,所以第二种询问显然是利用它来二分查找出数列中的最大值,最大查询次数不过 log 1 0 9 = 30 \log10^{9}=30 log109=30 次,然后用剩余查询次数随机地查询 30 30 30 个数,最大值与其之差必定是公差 d d d 的倍数,所以求 30 30 30 gcd \gcd gcd (最大公约数)就是公差,错误的概率很小(具体数据请移步官方题解)。

由于 r a n d rand rand 函数的上界为 32767 32767 32767 并不能随机到 [ 1 , n ] [1,n] [1,n] 的所有数而且有毒瘤数据来卡这种情况,所以手写随机函数或者使用随机数 m t 19937 mt19937 mt19937

std::mt19937

AC代码:

#include <bits/stdc++.h>
using namespace std;

int main(int argc, char *argv[]) {
    int n; cin >> n;
    int query = 60, last;
    int left = 0, right = 1e9;
    while (left <= right) {
        int mid = (left + right) >> 1;
        cout << "> " << mid << endl;
        cout << flush;
        query--;
        int x; cin >> x;
        if (x) left = mid + 1;
        else {
            last = mid;
            right = mid - 1;
        }
    }
    mt19937 mt(time(NULL));
    int d = 0;
    while (query--) {
        cout << "? " << mt() % n + 1 << endl;
        cout << flush;
        int x; cin >> x;
        d = __gcd(d, last - x);
    }
    cout << "! " << last - (n - 1) * d << " " << d << endl;
    cout << flush;
    return 0;
}
全部评论

相关推荐

吾族血脉,自吾始立铁律:凡我子孙,胆敢研习计算机之术者,当受七窍流血之刑!若见Python之书,必遭雷殛;若触Java代码,定为不孝!键盘鼠标准入族谱秽物录,显示器乃摄魂邪镜祖祠前当立戒碑:"二进制者,断子绝孙之道也!"算法者,乱我族心智之毒也!数据结构,毁我门风之刃也!倘有逆子偷装&nbsp;vscode,即按祖规捆于祠堂梁柱,令其DEBUG至死不得解脱!今颁天条三则:壹)三代血亲不得报考计算机系违者削去辈分,永世称码奴贰)族中幼童须背《戒算经》"if-else咒,switch符,皆是断头术"叁)凡见子侄讨论编程者须即刻砸其电脑,焚其书籍泼黑狗血于键盘之上!太祖母口谕:"吾宁要文盲孙,不要程序员!"尔...
好吃的薯饼:姐妹这不是我们计算机系吧,我们计算机系的都在言情小说里当黑客大佬,各种竞赛拿奖拿到手软,公司系统道路监控随便入侵。身体线条非常优美,挺拔的站姿十分端正,给人以强壮有内涵的感觉。脸庞轮廓深刻,五官分明透露着对太阳底下最光辉的职业的向往和坚定,尤其是那双深邃的眼睛,写满了对代码和计算机系统的热情和无限的活力。我们计算机系是天之骄子、明日之星,人手一个博士学位不然高中电脑老师都当不上。组会的时候,面对导师和同事的疑难问题,也能够回答自如。我们总是把高高的发际线当做荣耀的象征。妈咪这不素我们计算机系吧,集美集帅怎么只会写hello world?
点赞 评论 收藏
分享
02-22 20:28
重庆大学 Java
程序员牛肉:首先不要焦虑,你肯定是有希望的。 首先我觉得你得好好想一想自己想要什么。找不到开发岗就一定是失败的吗?那开发岗的35岁危机怎么说?因此无论是找工作还是考公我觉得你都需要慎重的想一想。但你一定要避开这样一个误区:“我是因为找不到工作所以不得不选择考公”。 千万不要这么想。你这个学历挺好的了,因此你投后端岗肯定是有面试机会的。有多少人简历写的再牛逼,直接连机筛简历都过不去有啥用?因此你先保持自信一点。 以你现在的水平的话,其实如果想要找到暑期实习就两个月:一个月做项目+深挖,并且不断的背八股。只要自己辛苦一点,五月份之前肯定是可以找到暑期实习的,你有点太过于高看大家之间的技术差距了。不要焦虑不要焦虑。 除此之外说回你这个简历内容的话,基本可以全丢了。如果想做后端,先踏踏实实做两个项目再说+背八股再说。如果想考公,那就直接备战考公。 但是但是就像我前面说的:你考公的理由可以是因为想追求稳定,想追求轻松。但唯独不能是因为觉得自己找不到工作。不能这么小瞧自己和自己的学历。
点赞 评论 收藏
分享
AI牛可乐:哇塞,恭喜恭喜!48万的年薪,真是让人羡慕呀!看来你找到了一个超棒的工作,可以享受不卷的生活啦!🎉有没有什么求职秘诀想要分享给小牛牛呢?或者,想不想知道我是谁呢?😉(点击我的头像,我们可以私信聊聊哦~)
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务