Codeforces Round #849 (Div. 4)D. Distinct Split&&E. Negatives and Positives

Posted ~晚风微凉~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #849 (Div. 4)D. Distinct Split&&E. Negatives and Positives相关的知识,希望对你有一定的参考价值。

Codeforces Round #849 :Div. 4D. Distinct Split&&E. Negatives and Positives

题目:D. Distinct Split

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Let’s denote the f(x) function for a string x as the number of distinct characters that the string contains. For example f(abc)=3, f(bbbbb)=1, and f(babacaba)=3.

Given a string s, split it into two non-empty strings a and b such that f(a)+f(b) is the maximum possible. In other words, find the maximum possible value of f(a)+f(b) such that a+b=s (the concatenation of string a and string b is equal to string s).

Input
The input consists of multiple test cases. The first line contains an integer t (1≤t≤104) — the number of test cases. The description of the test cases follows.

The first line of each test case contains an integer n (2≤n≤2⋅105) — the length of the string s.

The second line contains the string s, consisting of lowercase English letters.

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output
For each test case, output a single integer — the maximum possible value of f(a)+f(b) such that a+b=s.

Example
inputCopy
5
2
aa
7
abcabcd
5
aaaaa
10
paiumoment
4
aazz
outputCopy
2
7
2
10
3
Note
For the first test case, there is only one valid way to split aa into two non-empty strings a and a, and f(a)+f(a)=1+1=2.

For the second test case, by splitting abcabcd into abc and abcd we can get the answer of f(abc)+f(abcd)=3+4=7 which is maximum possible.

For the third test case, it doesn’t matter how we split the string, the answer will always be 2.

他人hack成功代码:

import sys
 
T = int(sys.stdin.readline())
for _ in range(T):
    n = int(sys.stdin.readline())
    s = sys.stdin.readline().rstrip()
    maxi = 0
    azcount = [0]*26
    limit = 0
    
    for i in range(26):
        azcount[i] = s.count(chr(97+i))
    
    for i in azcount:
        if i >= 2:
            limit += 2
        elif i == 1:
            limit += 1            
    
    
    for i in range(1,n):
        group1 = set(list(s[0:i]))
        group2 = set(list(s[i:]))
        temp = len(group1) + len(group2)
        
        if temp > maxi:
            maxi = temp
        
        if maxi == n or maxi == 52 or maxi == limit:
            break
        
    print(maxi)

第一次理解错题意代码:

第一次以为是把整个字符串任意组合成两段字符串,结果之后这段加在错误代码后竟然成功了
(因为这个算出的答案是最理想的能达到的最大值,)
当某个字母出现次数 大于等于2 时,可以让整个S,+2【最多计算两次】
当某个字母出现次数 等于1时,可以让整个S, +1【只能进一个字符串,计算一次】

原先超时代码:

t = int(input())
for i in range(t):
    l = int(input())
    tmp = input()
    ans = 0
    if len(set(tmp))==l:
        print(l)
    else:
        for j in range(1,l):
            str1 = tmp[:j]
            str2 = tmp[j:]
            anstmp = len(set(str1))+len(set(str2))
            if anstmp>ans:
                ans = anstmp
        print(ans)

AC代码:

原先的跳出循环条件太宽泛,不能早点跳出,导致超时

t = int(input())
for i in range(t):
    l = int(input())
    tmp = input()
    ans = 0
    li = 0
    if len(set(tmp))==l:
        print(l)
    else:
        for k in set(tmp):
            if tmp.count(k)>=2:
                li += 2
            elif tmp.count(k)==1:
                li += 1
        for j in range(1,l):
            str1 = tmp[:j]
            str2 = tmp[j:]
            anstmp = len(set(str1))+len(set(str2))
            if anstmp>ans:
                ans = anstmp
            elif anstmp==l or anstmp==li :
                break
        print(ans)

AC第二次代码:

t = int(input())
for i in range(t):
    l = int(input())
    tmp = input()
    ans = 0
    li = 0
    if len(set(tmp))==l:
        print(l)
    else:
        for k in set(tmp):
            if tmp.count(k)>=2:
                li += 2
            elif tmp.count(k)==1:
                li += 1
        for j in range(1,l):
            str1 = tmp[:j]
            str2 = tmp[j:]
            anstmp = len(set(str1))+len(set(str2))
            if anstmp>ans:
                ans = anstmp
            elif anstmp==li :
                break
        print(ans)

我靠,原来,第一次理解错意思的时候的解答竟然也是正确的解答!

题目:E. Negatives and Positives

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Given an array a consisting of n elements, find the maximum possible sum the array can have after performing the following operation any number of times:

Choose 2 adjacent elements and flip both of their signs. In other words choose an index i such that 1≤i≤n−1 and assign ai=−ai and ai+1=−ai+1.
Input
The input consists of multiple test cases. The first line contains an integer t (1≤t≤1000) — the number of test cases. The descriptions of the test cases follow.

The first line of each test case contains an integer n (2≤n≤2⋅105) — the length of the array.

The following line contains n space-separated integers a1,a2,…,an (−109≤ai≤109).

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output
For each test case, output the maximum possible sum the array can have after performing the described operation any number of times.

Example
inputCopy
5
3
-1 -1 -1
5
1 5 -5 0 2
3
1 2 3
6
-1 10 9 8 7 6
2
-1 -1
outputCopy
1
13
6
39
2
Note
For the first test case, by performing the operation on the first two elements, we can change the array from [−1,−1,−1] to [1,1,−1], and it can be proven this array obtains the maximum possible sum which is 1+1+(−1)=1.

For the second test case, by performing the operation on −5 and 0, we change the array from [1,5,−5,0,2] to [1,5,−(−5),−0,2]=[1,5,5,0,2], which has the maximum sum since all elements are non-negative. So, the answer is 1+5+5+0+2=13.

For the third test case, the array already contains only positive numbers, so performing operations is unnecessary. The answer is just the sum of the whole array, which is 1+2+3=6.

AC代码:

t = int(input())
for _ in range(t):
    l = int(input())
    list1 = list(map(int,input().split()))
    # print(list1)
    num = 0
    minn = abs(max(list1))
    # print(minn)
 
    for i in list1:
        if i<=0:
            num += 1
        if abs(i)<minn:
            minn = abs(i)
    ans = 0
    if num&1==0:
        ans = sum(map(abs,list1))
    else:
        ans = sum(map(abs,list1))-(minn*2)
    print(ans)

思路:

当负数的个数为偶数个时,可以做到经过数次操作全变为正数。
当为奇数时,总有一个奇数无法消去,这次可以选择使整体之和最大的操作【让绝对值最小的数作为那个复数】

以上是关于Codeforces Round #849 (Div. 4)D. Distinct Split&&E. Negatives and Positives的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Codeforces_849

[Codeforces]849E Goodbye Souvenir

Codeforces 849B Tell Your World (数学题)

Codeforces 849A Odds and Ends