20220820网易笔试

四道算法题+一道陈述题

  1. 有一个长度为n的数组是1到n的排列,现在我们每次可以进行一个操作,选择数组中第i个数和第j个数,对第i个数减去1而对第j个数加上1,要求操作后,数组中仍为一个1到n的排列。要求进行尽可能少的操作次数后,使得数组是非递减的。按顺序输出操作,答案可能有很多种,任意一种合理的即可。
"""
假定我们在一次操作中选中了a与b两个数字,a+=1 b-=1,
由于操作后数组仍为全排列,因此必定有set(a,b)=set(a-1,b+1)。
于是有a-1=b,即我们每次进行的操作必定是选两个值相差1的数,
其实就相当于交换二者的位置。
那我们可以贪心地求解这个问题,从前往后为第i个位置找到其主人
如果当前的nums[i]是大于i+1的,那么我们不断地进行操作使得这
个位置上的数字减去1,直到nums[i]=i+1即可
"""
def func1(arr):
    #输出操作使得arr是升序的
    #每次操作后都必须保证是一个排列,说白了就是a b变成a+1 b-1 有a = b-1
    #即每次可以交换大小差距为1的两个数的位置 所以对nums[i] 可以进行nums[i]-i+1
    dic={}#dic[i]记录数字i在arr中的下标
    for i,a in enumerate(arr):
        dic[a] = i
    times = 0
    ans = []
    for i in range(len(arr)):
        while arr[i] != i + 1:
            #将arr[i]与arr[i]-1交换位置
            times += 1
            a = dic[arr[i]]#得到需要交换的两个数字的下标
            b = dic[arr[i]-1]
            ans.append((b,a))
            dic[arr[i]] = b#记录更改后的下标
            dic[arr[i]-1] = a
            cur = arr[i]
            arr[a] = cur-1#进行位置交换
            arr[b] = cur
    print(times)
    for a,b in ans:
        print(a,b)

2.有一个由字母r,e,d组成的字符串,问其中有多少个子串满足其中三种字母的数目一样多。

"""
可以记录s[0:i]中三种字母的数字信息,只需要用一个大小为2的tuple=(a,b)即可描述此时三种字母的差值,a=count(e)-count(r)  b = count(d)-count(r)
如果一个子串s[i:j]满足要求,必定有s[0:i]对应的差值信息与s[0:j]的差值信息相同。
因此我们可以用一个dic记录之前出现过(a,b)差值的位置
"""
import collections
#计算由r e d构成的字符串中有多少个子串中r e d数目相同
def func2(s1):
    dic = collections.defaultdict(int)
    r = 0#记录到目前为止,三种字母的出现次数
    e = 0
    d = 0
    ans = 0
    #dic[(a,b)] 代表三种字母出现的值的为 c, c+a, c+b的情况
    dic[(0,0)]+= 1
    for i in range(len(s1)):
        if s1[i] == 'r':
            r += 1
        elif s1[i] == 'e':
            e += 1
        else:
            d += 1
        #然后查找dic[(e-r,d-r)]的个数
        ans += dic[(e-r,d-r)]
        dic[(e-r,d-r)]+=1
    print(ans)

3.有一个数组arr,现在要从中挑选k个数来把它们做按位与运算,求最大值

"""
把arr中的每个数字都写成二进制形式后,我们可以从高位往低位遍历,
对第i位时,我们需要遍历arr中的a,将满足a[i]=1的a加入候选者列表。
遍历完后,如果此时候选者列表数目小于k,说明这一位上无法找到k个1,
因此答案的这一位必定为0;否则说明这一位上可以找到k个1,答案这一
位为1,并将arr置为候选者列表。继续对第i+1位重复这个过程
"""
def func3(arr,k):
    ans = [0 for i in range(30)]#决定最终答案每个数位上的结果
    temp = []
    for a in arr:
        cur = str(bin(a))[2:]
        if len(cur) < 30:
            cur = '0'*(30-len(cur))+cur
        temp.append(cur)

    for i in range(30):
        cur = []
        #代表当前检查第i位结果
        for a in temp:
            if a[i] == '1':
                cur.append(a)
        if len(cur) >= k:#代表这个位置上有超过k个数为1,所以答案此位置置为1,然后把候选者加入其中;否则此位置为0,保留全部参与者进行下一轮比试
            ans[i] = 1
            temp = cur
    result = 0
    for a in ans:
        result*=2
        result+=a
    print(result)
  1. 一个数列,第一项是a,第二项是b,随后的每一项等于前两项乘积后再平方,求第N项的值。因为值很大,所以答案对10**9+7取模。 a,b,N<1e12
"""
题目意思很简单,但是由于N较大,直接写肯定超时。我考试时也没想出来咋写,只能设了个限制,然后正常迭代来写。后面查了资料,发现可以用快速幂来优化
"""
#傻瓜版本,只过了60%
def func4(a,b,n):
	if n > 1e8:
		print(0)
		return
    a = a%(10**9+7)
    b = b%(10**9+7)
    if n == 1:
        print(a)
        return
    elif n == 2:
        print(b)
        return
    first = 0,
    second = b
    for i in range(2,n):
        cur=(first*second)%(10**9+7)
        cur = (cur*cur)%(10**9+7)
        first = second
        second = cur
    print(cur)

#快速幂版本
    """
    观察可以发现,我们可以把第i项写作[Ai,Bi]代表第i项是a的Ai次幂与b的Bi次幂的乘积
    有A0 = 1 A1 = 0   A2 = 2  A3= 4
    B0=0 B1=1  B2 = 2 B3 = 6
    发现有Ai+2   = [2  2       Ai+1
         Ai+1      1  0]  *   Ai
    因此可以得到AN         [2 2          A1
              AN-1  =(   1 0] )**(N-1)  *  A0
    
    同理得到    BN         [2 2             B1
              BN-1  =(   1 0] )**(N-1)  *  B0
    
    #我们用快速幂得到AN与BN后   再用快速幂求出a**AN与b**BN
    
    2 2     2 2       6  4    16  12
    1 0     1 0   =   2  2    6   4
    """
from functools import cache
MOD = 10**9+7
@cache
def fast(a,times):
	#用于快速求得a的times次幂
    if times == 0:
        return 1
    if times == 1:
        return a%MOD
    rest = times%2
    temp = fast(a, times//2)
    ans = temp*temp
    if rest:
        ans *= a
    return ans%MOD

def multi(a,b):
	#用于矩阵乘法
    a11,a12,a21,a22 = a
    b11,b12,b21,b22 = b
    c11 = a11*b11+a12*b21
    c12 = a11*b12+a12*b22
    c21 = a21*b11+a22*b21
    c22 = a21*b12+a22*b22
    return c11%(MOD-1),c12%(MOD-1),c21%(MOD-1),c22%(MOD-1)
	#有一个问题,就是矩阵的元可能过大,需不需要也取个模?根据费马小定理发现
	#,如果p是质数,a不是p的倍数,则a**(p-1)modp=1 于是我们对矩阵的元mod(p-1)
	#如果不用费马小定理优化还是会超时
@cache
def fast_matrix(a,times):
    a11, a12, a21, a22 = a
    if times == 0:
        return 1,0,0,1
    elif times == 1:
        return a11,a12,a21,a22
    rest = times%2
    t = fast_matrix(a,times//2)
    ans = multi(t,t)
    if rest:
        ans = multi(ans,a)
    return ans


#快速幂优化版本
def func4_new(a,b,n):
    a = a % MOD
    b = b % MOD
    if n == 0:
        return a
    elif n == 1:
        return b
    ans = fast_matrix((2,2,1,0),n-2)
    # print('ans:',ans)
    m11, m12, _, _ = ans
    A = fast(a,m12)
    B = fast(b,m11)
    print((A*B)%MOD)

陈述题:
讲讲怎么处
理同声传译中的1)多模态问题2)实时性翻译3)翻译涉及专业术语,在通用语料上的训练有偏差怎么解决

帮助你的研究生同学写好第一篇学术论文,你该怎么用NLP领域的知识解决这个问题

PS:最后吐个槽,一开始因为网络原因,我一直没法连上网页。于是我拨打了下图中的手机,结果显示该号码已停机。。。有点离谱。。。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值