【20190902】【校招笔试题】腾讯技术研究类和数据分析第二次笔试(2019.9.1)(待续)

问题1

思路及解答

本来个人思路是:统计每一个元素出现的个数,若是存在若干个元素之和等于全部元素个数的一半就是YES,反之是NO。(找的规律,我也不清楚问什么)python

按照这个思路能过好多测试用例,但提交以后经过率为0%,因此思路是错的,下面有两个反例说明这个错误。数组

所以思路应该是:统计全部元素的个数,若是 “全部元素个数 < 全部元素个数之和的一半(或者元素的最大次数 < 全部元素个数之和的一半)”,那么就是YES,不然为NO。能够这样理解:对于任意元素【x】,若是要使能把【x】消掉,那么【非x 】的个数要大于等于【x】的个数,也就是说【x】的个数不能大于全部元素个数的一半。对于元素【x】,其余的元素都是【非x】,分析问题宏观来看。测试

心得:若是经过率为0%,那么就想是否是思路错了,而不是有边界条件或者没考虑彻底!优化

# 正确的代码(统计元素个数能够用哈希表也能够用数组)
T = int(input())
for _ in range(T):
    n = int(input())
    a = list(map(int, input().split()))
    dic = {}
    for item in a:
        if item in dic:
            dic[item] += 1
        else:
            dic[item] = 1
    if max(dic.values()) > len(a)//2:
        print("NO")
    else:
        print("YES")



################# 个人错误代码(思路错的) ################## 
T = int(input())
# T 组数据
for t in range(T):
    n = int(input())
    a = list(map(int, input().split()))
    # 存取个元素个数
    dic = {}
    for i in range(n):
        if a[i] not in dic:
            dic[a[i]] = 1
        else:
            dic[a[i]] += 1
    l = len(list(set(a)))
    count = list(dic.values())
    count.sort()
    target = sum(count) // 2
    if l == n:
        print("YES")
        continue
    if count[-1] > target:
        print("NO")
        continue
    if target in count:
        print("YES")
        continue
    else:
        for start in range(l):
            flag = 0
            if flag == 0:
                for end in range(start+1, l):
                    if sum(count[start:end+1]) == target:
                        print("YES")
                        flag = 1
                        break
                    elif sum(count[start:end+1]) < target:
                        continue
                    else:
                        break
            else:
                break
        if flag == 0:
            print("NO")
            continue

问题2

思路及解答

# 思路:相似于爬楼梯,以第i个长度为例,那么第i-1个长度只能是1个红花或k个白花t, k = list(map(int, input().split())),若是是1个红花,说明是从第i-1个位置“爬”过来的,若是是k个红花,说明是从i-k那个长度“爬”过来的,因此就是dp[i] = dp[i-1] + dp[i-k]。
t, k = list(map(int, input().split()))
N = 100001
tmp = 10**9 + 7
for _ in range(t):
    length = list(map(int, input().split()))
    a, b = length[0], length[1]
    dp = [0] * N
    dp[0], dp[1] = 0, 1   # dp 的初始值
    for i in range(2, b+2):  # 由于加了一个 i=0, 因此索引要到 b+1
        dp[i] = dp[i-1] + dp[i-k]
    print(sum(dp[a+1:b+2]) % tmp)   # 加了一个 i=0,索引须要是从 a+1 到 b+1

问题3

思路及解答

问题4(还有待优化)

思路及解答

个人思路:spa

    (1) 若是字符串和输出字符串包含的元素种类不一样,那么该字符串不能够;3d

    (2) 若是字符串长度大于输出字符串长度,那么该字符串不能够;code

    (3) 其他状况用暴力法判断:复制字符串 i 次,看是否能够知足题目条件。blog

################### 个人代码60%(超时) ##################
n = int(input())   # 长度限制
T= input()   # 发送的字符串
m = int(input())   # 字符串个数
count = 0
for _ in range(m):
    strs = input()
    l = len(strs)
    if set(strs) != set(T):
        continue
    if l > len(T):
        continue
    else:
        i = 2
        strs0 = strs
        while len(strs) < n:
            strs = strs0 * i
            i += 1
        if strs[0:n] == T:
            count += 1
print(count)



################## 参考的代码(70%),虽然没有全A,但我以为挺好的 ################
n = int(input())   # 长度限制
T= input()   # 发送的字符串
m = int(input())   # 字符串个数
count = 0
for _ in range(m):
    strs = input()
    times = n // len(strs) + 1   # 是求待判断字符串应该复制几回才有可能输出那个字符串,这里加一是为了防止,n//len(strs)有余数的状况,那么不加一就会形成待判断字符串乘以这个次数,依旧长度小于T的长度。
    strs_new = strs_new * times  
    if strs_new[:n] == T:
        count += 1
    else:
        continue
print(count)

问题5

思路及解答

知识点

1. if _name_ == "main":索引

2. 输入的两种方式字符串

3. Python 中 class 类、self 的用法