[解题报告] CSDN竞赛第14期

Posted lijiancheng0614

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[解题报告] CSDN竞赛第14期相关的知识,希望对你有一定的参考价值。

CSDN编程竞赛报名地址:https://edu.csdn.net/contest/detail/28

1. 字符串全排列

题目

对K个不同字符的全排列组成的数组, 面试官从中随机拿走了一个, 剩下的数组作为输入, 请帮忙找出这个被拿走的字符串?
比如[“ABC”, “ACB”, “BAC”, “CAB”, “CBA”] 返回 “BCA”

输入描述:

第一行输入整数n,表示给定n个字符串。(n == x!-1,2<=x<=10)
以下n行每行输入一个字符串。

输出描述:

输出全排列缺少的字符串。

输入

5
ABC
ACB
BAC
CAB
CBA

输出

BCA

解题报告

模拟,由于全排列的排列有偶数个,故序列中某个字符出现奇数个,就说明它是缺少的那一个

遍历每个排列的每个字符,对每个字符进行异或操作即可(因为异或会把偶数次的字符抵消掉,剩下奇数个的字符)

class Solution:
    def __init__(self) -> None:
        pass

    def solution(self, n, vector):
        if n == 0:
            return ''
        m = len(vector[0])
        if n == 1:
            return ''.join([vector[0][m - i - 1] for i in range(m)])
        s = [vector[0][j] for j in range(m)]
        for i in range(1, n):
            for j in range(m):
                s[j] = chr(ord(s[j]) ^ ord(vector[i][j]))
        return ''.join(s)


if __name__ == "__main__":
    n = int(input().strip())
    vector = []
    for i in range(n):
        vector.append(input().strip())
    sol = Solution()
    result = sol.solution(n, vector)
    print(result)

2. 小Q新式棋盘

题目

已知棋盘大小为n*n。 每个位置都有自己的权值q。 该棋盘中有多少对行权值和小于列权值和。

输入描述:

第一行输入整数n。(1<=n<=100)表示棋盘的大小
以下n行每行输入n个整数表示棋子的权值。(1<=a<=1000)

输出描述:

输出小Q的分值。

输入样例:

3
1 2 3
1 2 3
1 2 3

输出样例:

3

输入样例2:

3
4 5 6
2 3 4
3 2 1

输出样例2:

5

解题报告

模拟,计算每行每列的权值和,比较并统计

class Solution:
    def __init__(self) -> None:
        pass

    def solution(self, n, vector):
        l = [0] * n
        r = [0] * n
        for i in range(n):
            for j in range(n):
                l[i] += vector[i][j]
                r[j] += vector[i][j]
        s = 0
        for i in range(n):
            for j in range(n):
                if l[i] < r[j]:
                    s += 1
        return s


if __name__ == "__main__":
    n = int(input().strip())
    vector = []
    for i in range(n):
        vector.append([int(item) for item in input().strip().split()])
    sol = Solution()
    result = sol.solution(n, vector)
    print(result)

3. 因数-数字游戏

题目

小Q的柠檬汁做完了。 掏出了自己的数字卡牌。 想要和别人做数字游戏。 可是她又不想要输掉游戏。 她制定好规则,每次每个人只能把这个牌换成它的因子的某个牌。 但是这个因子不能是1或者整数本身。 现在给出整数n。 两个人开始做游戏,谁无法再给出因子牌则该人胜利,如果该整数无因子牌直接视为先手胜利,请判断先手在最优策略状态下能否必胜,

输入描述:

第一行输入整数n

输出描述:

输出先手在最优策略状态下能否必胜,如果能则输出1,不能则输出2

输入样例:

6

输出样例:

2

输入样例2:

30

输出样例2:

1

解题报告

博弈

  1. 若 n 为质数,则先手胜
  2. 若 n 只有两个因数(除1和本身外),则后手胜
  3. 若 n 有大于两个因数(除1和本身外),则先手可以制造出第二种情况,先手胜
class Solution:
    def __init__(self) -> None:
        pass

    def solution(self, n):
        v = []
        i = 2
        while i * i <= n:
            while n % i == 0:
                v.append(i)
                n = n // i
            i += 1
        if n > 1:
            v.append(n)
        if len(v) == 2:
            return 2
        return 1


if __name__ == "__main__":
    n = int(input().strip())
    sol = Solution()
    result = sol.solution(n)
    print(result)

4. 编码

题目

编码工作常被运用于密文或压缩传输。这里我们用一种最简单的编码方式进行编码:把一些有规律的单词编成数字。 字母表中共有26个字母a,b,…,z,这些特殊的单词长度不超过6且字母按升序排列。把所有这样的长度相同的单词放在一起,按字典顺序排列(a…z,ab…az,bc…bz…)一个单词的编码就对应着它在整个序列中的位置。 你的任务就是对于所给的单词,求出它的编码。

输入描述:

仅一行,被编码的单词。

输出描述:

仅一行,对应的编码。如果单词不在序列中,输出0。

输入样例:

ab

输出样例:

27

输入样例2:

glq

输出样例2:

1882

解题报告

数学/动态规划,如果给定字符串不是升序的,则输出 0

数学:根据给定字符串的长度 n,可知编号至少在 ∑ i = 1 n − 1 C 26 i \\sum_i = 1^n - 1 C_26^i i=1n1C26i 之后

遍历每个字符,第 i 个字符要从前一个字符的下一个字符开始(第 0 个字符则从第 1 个字符开始)计算编号,一直计算到第 i 个字符,把这些字符间的编号数统计起来,即

∑ j = w o r d [ i − 1 ] + 1 w o r d [ i ] − 1 C 26 − j n − i − 1 \\sum_j = word[i - 1] + 1^word[i] - 1 C_26 - j^n - i - 1 j=word[i1]+1word[i]1C26jni1

把上述编号求和即为所求编号

动态规划:设 f[i][j] 表示以字母 j 为开头的 i 位数的数量,则 f[i][j] = f[i − 1][j + 1] + f[i][j + 1],其中 f[1][j] = 1

同上遍历每个字符统计字符间的编号数,则

所求编号为 f [ n − i ] [ w o r d [ i ] ] + ∑ j = w o r d [ i − 1 ] + 1 w o r d [ i ] − 1 f [ n − i ] [ j ] f[n - i][word[i]] + \\sum_j = word[i - 1] + 1^word[i] - 1 f[n - i][j] f[ni][word[i]]+j=word[i1]+1word[i]1f[ni][j]

class Solution:
    def __init__(self) -> None:
        pass

    def C(self, n, m):
        s = 1
        for i in range(1, m + 1):
            s = s * (n - m + i) // i
        return s

    def solution(self, word):
        n = len(word)
        for i in range(1, n):
            if word[i] <= word[i - 1]:
                return 0
        s = 1
        for i in range(1, n):
            s += self.C(26, i)
        z = ord('z') - ord('a')
        for i in range(n):
            j = 0 if i == 0 else ord(word[i - 1]) - ord('a') + 1
            k = ord(word[i]) - ord('a')
            while j < k:
                s += self.C(z - j, n - i - 1)
                j += 1
        return s


if __name__ == "__main__":
    word = input().strip()
    sol = Solution()
    result = sol.solution(word)
    print(result)

以上是关于[解题报告] CSDN竞赛第14期的主要内容,如果未能解决你的问题,请参考以下文章

[解题报告] CSDN竞赛第五期

[解题报告] CSDN竞赛第22期

[解题报告] CSDN竞赛第22期

[解题报告] CSDN竞赛第21期

[解题报告] CSDN竞赛第21期

[解题报告] CSDN竞赛第17期