[解题报告] 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
解题报告
博弈
- 若 n 为质数,则先手胜
- 若 n 只有两个因数(除1和本身外),则后手胜
- 若 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=1n−1C26i 之后
遍历每个字符,第 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[i−1]+1∑word[i]−1C26−jn−i−1
把上述编号求和即为所求编号
动态规划:设 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[n−i][word[i]]+j=word[i−1]+1∑word[i]−1f[n−i][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期的主要内容,如果未能解决你的问题,请参考以下文章