Codeforces Round #690 (Div. 3)补题

题目链接

文章目录

  • A. Favorite Sequence
  • B. Last Year's Substring
  • C. Unique Number
  • D. Add to Neighbour and Remove
  • E. Close Tuples (hard version)
  • F. The Treasure of The Segments

A. Favorite Sequence

Polycarp has a favorite sequence a[1…n] consisting of n integers. He wrote it out on the whiteboard as follows:

he wrote the number a1 to the left side (at the beginning of the whiteboard);
he wrote the number a2 to the right side (at the end of the whiteboard);
then as far to the left as possible (but to the right from a1), he wrote the number a3;
then as far to the right as possible (but to the left from a2), he wrote the number a4;
Polycarp continued to act as well, until he wrote out the entire sequence on the whiteboard.
The beginning of the result looks like this (of course, if n≥4).
For example, if n=7 and a=[3,1,4,1,5,9,2], then Polycarp will write a sequence on the whiteboard [3,4,5,2,9,1,1].

You saw the sequence written on the whiteboard and now you want to restore Polycarp’s favorite sequence.
思路:没什么特别好说的,就是取首尾元素

for i in range(int(input())):
    n=int(input())
    ls=list(map(int,input().split()))
    sequence=[]
    for i in range(len(ls)//2):
        sequence.append(ls[i])
        sequence.append(ls[-i-1])
    if len(ls)%2==0:
        print(" ".join(map(str,sequence)))
    else:
        sequence.append(ls[len(ls)//2])
        print(" ".join(map(str,sequence)))

B. Last Year’s Substring

Polycarp has a string s[1…n] of length n consisting of decimal digits. Polycarp performs the following operation with the string s no more than once (i.e. he can perform operation 0 or 1 time):

Polycarp selects two numbers i and j (1≤i≤j≤n) and removes characters from the s string at the positions i,i+1,i+2,…,j (i.e. removes substring s[i…j]). More formally, Polycarp turns the string s into the string s1s2…si−1sj+1sj+2…sn.
For example, the string s=“20192020” Polycarp can turn into strings:

“2020” (in this case (i,j)=(3,6) or (i,j)=(1,4));
“2019220” (in this case (i,j)=(6,6));
“020” (in this case (i,j)=(1,5));
other operations are also possible, only a few of them are listed above.
Polycarp likes the string “2020” very much, so he is wondering if it is possible to turn the string s into a string “2020” in no more than one operation? Note that you can perform zero operations.
思路:通过移走一个区间,使剩下的字符串可以写成2020的形式(不可以带其他数字,一开始我理解错了),所以实际上就几种固定的情况

for i in range(int(input())):
    n=int(input())
    a=input()
    if a=="2020":
        print("YES")
    else:
        flag=0
        if a.startswith("2")and a.endswith("020") or a.startswith("20")and a.endswith("20") or a.startswith("202")and a.endswith("0") or a.startswith("2020") or a.endswith("2020"):
            flag=1
        if flag==1:
            print("YES")
        else:
            print("NO")

C. Unique Number

You are given a positive number x. Find the smallest positive integer number that has the sum of digits equal to x and all digits are distinct (unique).
思路:输出最小的数位和等于x并且各个数位都不一样的值,这里数据量只有50个所以哪怕暴力都不用写很久。因为题目要求最小,所以把大的放最后,从9到1依次

for i in range(int(input())):
    number=int(input())
    if 1<=number<=9:
        print(number)
    elif 45<number<=50:#各个位从1到9相加最大值为45,所以超过45肯定就不行了
        print(-1)
    else:
        a=""
        for i in range(9,0,-1):
            if number-i>0:
                a+=str(i)
                number-=i
            else:
                a+=str(number)
                break
        print(a[::-1])

D. Add to Neighbour and Remove

Polycarp was given an array of a[1…n] of n integers. He can perform the following operation with the array a no more than n times:

Polycarp selects the index i and adds the value ai to one of his choice of its neighbors. More formally, Polycarp adds the value of ai to ai−1 or to ai+1 (if such a neighbor does not exist, then it is impossible to add to it).
After adding it, Polycarp removes the i-th element from the a array. During this step the length of a is decreased by 1.
The two items above together denote one single operation.

For example, if Polycarp has an array a=[3,1,6,6,2], then it can perform the following sequence of operations with it:

Polycarp selects i=2 and adds the value ai to (i−1)-th element: a=[4,6,6,2].
Polycarp selects i=1 and adds the value ai to (i+1)-th element: a=[10,6,2].
Polycarp selects i=3 and adds the value ai to (i−1)-th element: a=[10,8].
Polycarp selects i=2 and adds the value ai to (i−1)-th element: a=[18].
Note that Polycarp could stop performing operations at any time.

Polycarp wondered how many minimum operations he would need to perform to make all the elements of a equal (i.e., he wants all ai are equal to each other).
思路:见注释部分

for i in range(int(input())):
    length=int(input())
    ls=list(map(int,input().split()))
    if len(ls)==1 or ls.count(ls[0])==len(ls):
        print(0)
    else:
        res=len(ls)-1
        s=sum(ls)
        #反过来遍历是因为题目要求操作的最小值
        for i in range(length-1,1,-1):
            if s%i==0:
                cur=0
                need=s//i
                ans = 0
                flag = 1
                for j in range(len(ls)):
                    cur+=ls[j]
                    if cur>need:#如果出现大于的就退出,因为只能做加法运算,超过预算值一定是不符合的
                        flag=0
                        break
                    elif cur==need:
                        cur=0
                if flag==1:
                    res=length-i#原长度减现在长度就是操作的次数
                    break
        print(res)

E. Close Tuples (hard version)

This is the hard version of this problem. The only difference between the easy and hard versions is the constraints on k and m. In this version of the problem, you need to output the answer by modulo 109+7.

You are given a sequence a of length n consisting of integers from 1 to n. The sequence may contain duplicates (i.e. some elements can be equal).

Find the number of tuples of m elements such that the maximum number in the tuple differs from the minimum by no more than k. Formally, you need to find the number of tuples of m indices i1

max(ai1,ai2,…,aim)−min(ai1,ai2,…,aim)≤k.
For example, if n=4, m=3, k=2, a=[1,2,4,3], then there are two such triples (i=1,j=2,z=4 and i=2,j=3,z=4). If n=4, m=2, k=1, a=[1,1,1,1], then all six possible pairs are suitable.

As the result can be very large, you should print the value modulo 109+7 (the remainder when divided by 109+7).
思路:hard和easy差不多就直接做hard了。题目就是要求n个数中m元组满足最大值减最小值小于等于k的个数。在计算组合数时因为要求模所以这里涉及阶乘逆元的知识。而在枚举过程中,我的做法是先固定一维限定并计算另一维,比如说这里我先枚举最小值,通过二分找到符合要求的最大值,接着用组合数公式累加方案个数。

import bisect
mod=10**9+7
N=200001
fact=[1]
for i in range(1,N+1):
    fact.append((fact[-1]*i)%mod)
def nCr(n,r):
    if n<=r:
        return n==r
    a=fact[n]
    b=(fact[n-r]*fact[r])%mod
    b=pow(b,mod-2,mod) #除法不能取模,故要求逆元
    #(a*b)%p=(a%p*b%p)%p
    return (a * b) % mod
for i in range(int(input())):
    n,m,k=map(int,input().split())
    ans=0
    sequence=list(map(int,input().split()))
    if sequence.count(sequence[0])==len(sequence): 
        print(nCr(len(sequence),m)%mod)
    else:
        sequence.sort()
        for j in range(n-m+1):
            last=bisect.bisect_right(sequence,sequence[j]+k)#找到最大的能满足小于等于k的数
            ans+=nCr(last-j-1,m-1)
            """
            例如在[1, 1, 2, 2, 3, 4, 5, 6, 8, 9, 0],m=4,k=3中,固定了1后找到最后一个符合要求的是4
            那么1对应位置的答案就是1到4[1,4)当中5个数选择(m-1)个数即c53
            """
        print(ans%mod)

F. The Treasure of The Segments

Polycarp found n segments on the street. A segment with the index i is described by two integers li and ri — coordinates of the beginning and end of the segment, respectively. Polycarp realized that he didn’t need all the segments, so he wanted to delete some of them.

Polycarp believes that a set of k segments is good if there is a segment [li,ri] (1≤i≤k) from the set, such that it intersects every segment from the set (the intersection must be a point or segment). For example, a set of 3 segments [[1,4],[2,3],[3,6]] is good, since the segment [2,3] intersects each segment from the set. Set of 4 segments [[1,2],[2,3],[3,5],[4,5]] is not good.

Polycarp wonders, what is the minimum number of segments he has to delete so that the remaining segments form a good set?
思路:题目想求最少删除几个线段,使得剩下线段中,有至少一个线段与所有线段相交。那么我们反过来想一下线段不相交的条件,如对于两个区间(li,ri)(lj,rj)来说 lj>ri or rj

import bisect
for _ in range(int(input())):
    n=int(input())
    ls=[]
    lsl=[]
    lsr=[]
    for _ in range(n):
        l,r=map(int,input().split())
        ls.append([l,r])
        lsl.append(l)
        lsr.append(r)
    lsl.sort()
    lsr.sort()
    cnt=float("inf")
    for i in range(n):
        bad_left=bisect.bisect_left(lsr,ls[i][0])
        bad_right=bisect.bisect_right(lsl,ls[i][1])
        #右端点和后面的左端点比,所以最后是n-bad_right
        cnt=min(cnt,n-bad_right+bad_left)
    print(cnt)

你可能感兴趣的:(OJ题解,python)