腾讯2018春招技术类编程题汇总
1. 翻转序列
小Q定义了一种数列称为翻转数列:
给定整数n和m, 满足n能被2m整除。对于一串连续递增整数数列1, 2, 3, 4…, 每隔m个符号翻转一次, 最初符号为’-’;。
例如n = 8, m = 2, 数列就是: -1, -2, +3, +4, -5, -6, +7, +8.
而n = 4, m = 1, 数列就是: -1, +2, -3, + 4.
解析:
首先观察数列,我们可以将一组负正的数出现(如-1,-2,3,4)看做一组,则n个数一共有n/(2m)组,而每一组求和结果为mm,
于是得到前n项和公式为Sn = nmm/2m = mn/2
n,m = map(int,input().split())
print(m*n//2) # m*n/2 输出为float形式
2.纸牌游戏
牛牛和羊羊正在玩一个纸牌游戏。这个游戏一共有n张纸牌, 第i张纸牌上写着数字ai。
牛牛和羊羊轮流抽牌, 牛牛先抽, 每次抽牌他们可以从纸牌堆中任意选择一张抽出, 直到纸牌被抽完。
他们的得分等于他们抽到的纸牌数字总和。
现在假设牛牛和羊羊都采用最优策略, 请你计算出游戏结束后牛牛得分减去羊羊得分等于多少。
n = int(input())
a = list(map(int,input().split()))
a.sort(reverse=True)
s = 0
for i in range(n):
s += (-1)**i * a[i]
print(s)
n = input()
m = sorted(list(map(int, input().split())))
a = sum(m)
n = sum(m[::-2])
print(2*n-a)
3.贪吃的小Q(二分法)
小Q的父母要出差N天,走之前给小Q留下了M块巧克力。小Q决定每天吃的巧克力数量不少于前一天吃的一半,但是他又不想在父母回来之前的某一天没有巧克力吃,请问他第一天最多能吃多少块巧克力
解析:
n,m = map(int, input().split())
def countSugar(num,k):
res = 0
while k > 0:
res += num
num = (num+1)//2
k -= 1
return res
low,high = 1,m
while low < high:
mid = (low + high + 1) // 2
if countSugar(mid,n) <= m:
low = mid
else:
high = mid - 1
print(low)
4.小Q的歌单(01背包+压缩空间)
小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌,现在小Q想用这些歌组成一个总长度正好为K的歌单,每首歌最多只能在歌单中出现一次,在不考虑歌单内歌曲的先后顺序的情况下,请问有多少种组成歌单的方法。
背包问题
k = int(input().strip())
lx, x, ly, y = list(map(int, input().strip().split(" ")))
dp = [1] + [0] * k # 第一位初始化为1
for i in range(x):
for j in range(k, lx-1, -1):
dp[j] += dp[j-lx]
for i in range(y):
for j in range(k, ly-1, -ly): # 第二次步长为ly
dp[j] += dp[j-ly]
print(dp[k]%1000000007)
import sys
def parse_nums(nums_str):
return [int(x) for x in nums_str.strip().split()]
# 基本输入输出
for s in sys.stdin:
s = int(s)
v1, n1, v2, n2 = parse_nums(input())
v = [v1] * n1 + [v2] * n2
n = n1 + n2
dp = [0] * (s + 1)
dp[0] = 1
for i in range(n):
for j in range(s, v[i] - 1, -1):
dp[j] = (dp[j] + dp[j - v[i]]) % 1000000007
print(dp[s])