记牛客2018真题笔试刷(五)

目录

字符串问题(逐个字符串匹配,摩拜)

字符串匹配(逐个字符串匹配,百度)

寻找丑数(丑数判断)

双素数(素数判断)


字符串问题(逐个字符串匹配,摩拜)

题目描述

小摩手里有一个字符串A,小拜的手里有一个字符串B,B的长度大于等于A,所以小摩想把A串变得和B串一样长,这样小拜就愿意和小摩一起玩了。

而且A的长度增加到和B串一样长的时候,对应的每一位相等的越多,小拜就越喜欢。比如"abc"和"abd"对应相等的位数为2,为前两位。

小摩可以在A的开头或者结尾添加任意字符,使得长度和B一样。现在问小摩对A串添加完字符之后,不相等的位数最少有多少位?

输入描述:

第一行 为字符串A,第二行 为字符串B,
A的长度小于等于B的长度,B的长度小于等于100。
字符均为小写字母。

输出描述:

输出一行整数表示A串添加完字符之后,A B 不相等的位数最少有多少位?

示例1

输入

abe
cabc

输出

1

思路

先滤清条件,a串是短串,b串是长串,所以,匹配起来的话,每次改变b串的长度,就是将b的每个左侧第一个都删除,将删除后的剩下的b',和a逐个字符的相比较,来记录出来相同位相同的字符数量。那么如此遍历下来,就取极值就可以找到最优解了。

这个里面的一个点是,len(b)+1-len(a),代表的是因为题目要求比较的字串b’必须和a串的长度相同,所以,以题目提供的例子为例, a = abe,b = cabc,len(b) + 1 - (a) = 4+1-3 = 2,从b从索引0到索引3,分别是cab(0), abc(1)。和a串abe做比较。

因为getnum函数中,i是以len(a)为标准的,a多长,那输入的b就截取多长,这样保证了 相同位相同的字符数量。

code

def getnum(a,b):
    count = 0
    for i in range(len(a)):
        if a[i]==b[i]:
            count += 1
    return count


a = raw_input()
b = raw_input()

max_num = 0
for id in range(len(b)+1-len(a)):
    num = getnum(a, b[id:])
    if num >= max_num:
        max_num = num

print len(a)-max_num

 

字符串匹配(逐个字符串匹配,百度)

题目描述

牛牛有两个字符串A和B,其中A串是一个01串,B串中除了可能有0和1,还可能有'?',B中的'?'可以确定为0或者1。 寻找一个字符串T是否在字符串S中出现的过程,称为字符串匹配。牛牛现在考虑所有可能的字符串B,有多少种可以在字符串A中完成匹配。

例如:A = "00010001", B = "??"
字符串B可能的字符串是"00","01","10","11",只有"11"没有出现在字符串A中,所以输出3

输入描述:

输入包括两行,第一行一个字符串A,字符串A长度length(1 ≤ length ≤ 50),A中每个字符都是'0'或者'1'。
第二行一个字符串B,字符串B长度length(1 ≤ length ≤ 50),B中的字符包括'0','1'和'?'。

输出描述:

输出一个整数,表示能完成匹配的字符串种数。

示例1

输入

00010001
??

输出

3

思路

先判断边界条件:

    if len(B)>len(A):
        return 0

此题和上一题有相似的关系,都是用了,len(A) - length_B + 1,还是A串是长串,B串是短串,每次把A串连续切割成,和B串相同的长度的然后,和B比较下,相等的话,就把短的A,给存到res里面,最后,要记住去重,set(res),最最后,返回res的长度,就是返回个数了。

code

def solution(A,B):
    if len(B)>len(A):
        return 0
    length_B = len(B)
    count = 0
    res = []
    for i in range(len(A) - length_B + 1):
        tmp = 0
        for j in range(length_B):
            if B[j] == '?' or B[j] == A[i:i+length_B][j]:
                tmp += 1
                if tmp == length_B:
                    res.append(A[i:i+length_B])
            else:
                break
    return len(set(res))
if __name__=='__main__':
    A = raw_input().strip()
    B = raw_input().strip()
    print solution(A,B)

 

寻找丑数(丑数判断)

题目描述

把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

输入描述:

整数N

输出描述:

第N个丑数

示例1

输入

6

输出

6

思路

此题是经典例题,是遍历的思想,因为丑数只能是2,3,5的倍数,所以,我就从小到大依次来求丑数就行了,只要个数小于n,那么就开始将2,3,5(这是丑数里面最开始的三个),然后,选择三个里面最小的一个(因为要保证顺序排列),填入到丑数序列里面,因为不能保证2,3,5的倍数那个最大,那个最小,然后,都做一次比较,然后才可以,保证是顺序填入的。须练习,不熟。

code

n = int(raw_input())
num = [1]
numidx = 1
i, j, k = 0, 0,0
while numidx < n:
    minNum = min(num[i]*2, num[j]*3, num[k]*5)
    num.append(minNum)
    if minNum == num[i]*2:
         i += 1
    if minNum == num[j]*3:
         j += 1
    if minNum == num[k]*5:
         k += 1
    numidx += 1
 
print (num[numidx-1])

 

双素数(素数判断)

题目描述

一个正整数是素数当且仅当它除了1和自身以外没有其他因子,现在我们定义双素数;一个正整数是双素数当且仅当它本身是个素数,并且将他的十进制表示反转后得到数不等于它自身且也是个素数,如13就是一个双素数,因为13和31不相等且都是素数,现给出一个整数k,你需要找到第k小的双素数

输入描述:

第一行包含一个整数k,1≤k≤10000

输出描述:

若第k小的素数不超过10^6则输出它,否则输出-1

示例1

输入

1

输出

13

思路

先依据题意,来将边界条件给写清楚

  original = [1 for i in range(10**6)]

再说,质数又称素数。 一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。 0和1既不是质数也不是合数,最小的质数是2.

之前做过两道判断素数的题目(之前有记录),这次又是一个新的方法来判断素数。

这个作者这次做的比较“绝”,直接把范围内的所有素数都给标记成“0”

    for i in range(2,10**3+1):
        for j in range(i*2, 10**6, i):
            original[j] = 0

然后,再逐一从头和尾,挑选出对应的十进位交换数,同时判断,是否为素数

        if original[j] == 1: // 如果当前位为素数就进入下面的判断语句
            tmp = str(j)     // 先把这个数转换为str类型,为了下面好反转
            tmp = int(tmp[::-1]) // 将这个数字,从后向前倒序排列,相当于找它的十进位交换数
            if tmp != j and original[tmp] == 1: //如果十进位交换数也是素数,即对应位为1,那么说明是个双素数
                i += 1 // i累加记录

那么问题来了,那最后为什么返回的是j,不是i呢?因为题目要求的是返回素数本身,i是次数,j才是对应的素数本身。

code

def primelist(k):
    original = [1 for i in range(10**6)]
    original[0] = 0
    original[1] = 0
    for i in range(2,10**3+1):
        for j in range(i*2, 10**6, i):
            original[j] = 0
    i = 1
    j = 2
    while i <= k and j <= 10**6:
        if original[j] == 1:
            tmp = str(j)
            tmp = int(tmp[::-1])
            if tmp != j and original[tmp] == 1:
                i += 1
        j += 1
    if i <= k+1:
        return j - 1
    else:
        return -1
 
if __name__=='__main__':
    k = int(input())
    print(primelist(k))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值