1. 巨大的错误 (错排公式)
想象一个原来有序的书架,每本书都有原本的位置,现在要改变他们的位置,让每本书的位置都不是原来的位置。
现在假设我们有n本书,要打乱他们的顺序:
- 第n本书需要放到前n-1个位置,有n-1种选择,假设放到了位置k
- 位置k的书需要找一个位置放
- 如果放到了n,就相当于n,k互换位置,剩下的n-2本书是相同的子问题
- 如果没有放到n,那么可以想象k的位置原本就在n,k不能放在n,剩下的n-1本书是相同的子问题
因此递推公式就是 D ( n ) = ( n − 1 ) ∗ ( D ( n − 1 ) + D ( n − 2 ) ) D(n)=(n-1)*(D(n-1)+D(n-2)) D(n)=(n−1)∗(D(n−1)+D(n−2))
if __name__ == '__main__':n = int(input())a= [0] * 21a[1], a[2] = 0, 1for i in range(3,n+1):a[i] = (i-1)*(a[i-1]+a[i-2])print(a[n])
2. 歌词中找单词(二分)
首先遍历歌词,找到每一个歌词出现的位置,存到列表里,然后每次寻找字母位置的时候使用二分法,保证子序列的递增。
from collections import defaultdictif __name__ == '__main__':n = int(input())words = []for i in range(n):words.append(input())lyris = input()word_num = defaultdict(list)for index,word in enumerate(lyris):word_num[word].append(index)# 遍历每一个单词for word in words:flag = True# 上一个单词位置now = -1# 遍历每一个字母for j in word:l,r = 0, len(word_num[j])-1while l < r:mid = l + r >> 1if word_num[j][mid] > now:r = midelse:l = mid + 1if not word_num[j]:flag = Falsebreak# 到了最后一位,且不满足if l == len(word_num[j])-1 and word_num[j][l] < now:flag = Falsebreaknow = word_num[j][l]if flag:print('YES')else:print('NO')
3. 字符串斐波那契
递归,第n个字符串由n-1和n-2字符串得到,判断来自于哪个,继续递归。
def find(n,c):if n == 0:print(a0[c-1])returnif n == 1:print(a1[c-1])returnif c <= length[n-2]:find(n-2, c)else:find(n-1, c-length[n-2])if __name__ == '__main__':a0 = 'IAKIOI'a1 = 'WHENWILLSCORLLOFTAIWUCOMEOUT!!!'length = [0]*81length[0] = len(a0)length[1] = len(a1)n,c = map(int, input().split())for i in range(2, n+1):length[i] = length[i-1] + length[i-2]find(n,c)