2017年校招全国统一模拟笔试(第二场)编程题集合--Python

注:题目来源于牛客网。

1.

牛牛有两个字符串(可能包含空格),牛牛想找出其中最长的公共连续子串,希望你能帮助他,并输出其长度。 
输入描述:
输入为两行字符串(可能包含空格),长度均小于等于50.


输出描述:
输出为一个整数,表示最长公共连续子串的长度

个人思路:

我采用的是 [x:y] 不断获取字串的方式,以此来求最长。就纯遍历。
然后看到解析思路有一种:
/*思路:假设两个字符串str1和str2,长度分别为m和n,则构建一个m*n的矩阵matrix,
 
        matrix[i][j]==1表示字符串str1中第i个字符与str2中第j个字符相等,为0则不相等。
 
        统计矩阵matrix中每条斜线上1的连续最大个数就是str1和str2中公共连续子串的最大长度*/
 
/*例如:str1: abcde    str2: abgde 
 
       matrix = [ 1  0  0  0  0 
 
                  0  1  0  0  0
 
                  0  0  0  0  0
 
                  0  0  0  1  0
 
                  0  0  0  0  1 ]
 
     斜线上连续的1的最大个数为2,所以最长公共连续子串长度为2*/
哪里都离不开数学啊,给你一个眼神自己体会吧。
而下面的正确答案给则说出这道题其实考的算法是动态规划

正确答案(本人&&牛客网 id: )

s1 = raw_input()
s2 = raw_input()

len_arr = []
i = 0
m = 1
j = m
k = 1
z = 1
while j <= len(s1):
    temp = s1[i:j]
    if temp in s2:
        len_arr.append(len(temp))
    i += z
    j += z
    if j == len(s1)+1:
        k += 1
        i = 0
        m += 1
        j = m
    if len(temp) == len(s1):
        break
if len(len_arr) != 0:
    print max(len_arr)
else:
    print 0
矩阵方法:
def find_lcsubstr(s1, s2):
    # 生成0矩阵,为方便后续计算,比字符串长度多了一列
    m = [[0 for i in range(len(s2) + 1)] for j in range(len(s1) + 1)]
    # print m
    # 最长匹配的长度
    mmax = 0
    # 最长匹配对应在s1中的最后一位
    p = 0
    for i in range(len(s1)):
        for j in range(len(s2)):
            if s1[i] == s2[j]:
                m[i + 1][j + 1] = m[i][j] + 1
                if m[i + 1][j + 1] > mmax:
                    mmax = m[i + 1][j + 1]
                    p = i + 1
    # 返回最长子串及其长度
    #  s1[p - mmax:p]为公共字符串
    return mmax


if __name__ == "__main__":
    s1 = raw_input()
    s2 = raw_input()
    print find_lcsubstr(s1, s2)

# 算法解析: 解法就是用动态回归的思想,一个矩阵记录两个字符串中匹配情况,
# 若是匹配则为左上方的值加1,否则为左方和上方的最大值。
# 一个矩阵记录转移方向,然后根据转移方向,回溯找到最长子序列。


2.

牛牛想在[a, b]区间内找到一些数满足可以被一个整数c整除,现在你需要帮助牛牛统计区间内一共有多少个这样的数满足条件? 
输入描述:
首先输入两个整数a,b,(-5*10^8 ≤ a ≤ b ≤ 5*10^8)
接着是一个正整数c(1 <= c <= 1000)


输出描述:
输出一个整数表示个数

个人思路:

满足被一个数整除,个人觉得这道题不难。注意一点就是 c  的范围问题。但是,测试的时候总是报我莫名其妙的错误。

arr = [int(i) for i in raw_input().strip().split()]
c = int(raw_input())
a = arr[0]
b = arr[1]
count = 0
if a <= c <= b:
    num = xrange(a, c+1)
    for n in num:
        if c % n == 0:
            print n
            count += 1
    print count
elif c >= b:
    num = xrange(a, b+1)
    for n in num:
        if c % n == 0:
            count += 1
    print count
elif c < a:
    print count
一直给我说 C = int(raw_input) 错误错误。之前的那些输入,这样写都没毛病,就唯独这一个出问题了。

正确答案(牛客网 id:cheeeenkun):

input_ = map(int,raw_input().split())
a = input_[0]
b = input_[1]
c = input_[2]
 
max_value = b/c
min_value = a/c
if a%c == 0:
    print max_value-min_value+1
else:
    print max_value-min_value

就是分别求出俩区间 / c 的值,然后就可以得出结果!你说数学妙不妙。



3.

牛牛手里有N根木棒,分别编号为1~N,现在他从N根里想取出三根木棒,使得三根木棒构成一个三角形,你能计算出牛牛有多少种取法吗?(考虑两种取法中使用的木棒编号有一个不一样就认为是不同的取法)。 
输入描述:
首先输入一个正整数N,接下来的一行共有N个正整数表示每个木棒的长度。

N ≤ 50, 木棒的长度 ≤ 10000.


输出描述:
输出一个整数表示方法数。

个人思路:

先通过三个循环把所有可能,不论重复的三角形找出来。
然后通过对数组进行操作,去掉相同的三角形。奈何代码还是有错误,20% case。

正确答案(牛客网 id: 佩佩):

def Triangle(n, lengths):
    res =0
    lengths.sort()
    for i in range(n):
        for j in range(i+1,n):
            for k in range(j+1,n):
                if lengths[i]+lengths[j]>lengths[k]:
                    res+=1
                else: break
             
    return res
                 
 
if __name__=="__main__":
    #obj=Solution()
     
    n= int(raw_input().strip())
     
    lengths=map(int, raw_input().strip().split())
    print Triangle(n, lengths)
一眼相中了这个解法,我也知道自己的问题究竟在哪里,range 的参数啊,我怎么那么傻呢。



4.

牛牛在二维坐标系中画了N个点,且都是整点。现在牛牛想画出一个矩形,使得这N个点都在矩形内或者在矩形上。
矩形的边均平行于坐标轴。牛牛希望矩形的面积最小。请你帮助牛牛计算下最小矩形的面积。 
输入描述:
首先输入一个正整数N表示点的个数(2 <= N <= 50)
  
接下来N行每行两个整数x, y,表示该点的坐标。绝对值均小于等于100.


输出描述:
一个整数表示最小矩形的面积。

个人思路:

面积最小,点在矩形,两点距离,点到线...盘不动了。这题真的是不知道从何入手

正确答案(牛客网 id: Panzerfaust):

try:
    while True:
        num = int(raw_input())
        arr_x= []
        arr_y =[]
        for i in range(num):
            tmp = raw_input().split()
            arr_x.append(int(tmp[0]))
            arr_y.append(int(tmp[1]))
        min_x = min(arr_x)
        max_x = max(arr_x)
        min_y = min(arr_y)
        max_y = max(arr_y)
        print((max_x-min_x)*(max_y-min_y))
except:
    pass
不是,这题这么简单。最大最小坐标点的差相乘,就是结果。


5.

牛牛在研究他自己独创的平衡数,平衡数的定义是:将一个数分成左右两部分,分别成为两个新的数。
左右部分必须满足以下两点:
1,左边和右边至少存在一位。
2,左边的数每一位相乘如果等于右边的数每一位相乘,则这个数称为平衡数。
例如:1221这个数,分成12和21的话,1*2=2*1,则称1221为平衡数,再例如:1236这个数,可以分成123和1*2*3=6,所以1236也是平衡数。而1234无论怎样分也不满足平衡数。 
输入描述:
输入一个正整数(int范围内)。


输出描述:
如果该数是平衡数,输出 "YES", 否则输出 "NO"

个人思路:

python 中 [:X] [X:] 操作还是挺方便的,这题和上面那个一样,依次分割依次统计就好。

正确答案(本人):

n = raw_input()
arr = map(int, list(n))
i = 1
result = "NO"
while i < len(arr):
    before = arr[:i]
    after = arr[i:]
    B = 1
    A = 1
    for b in before:
        B = B * b
    for a in after:
        A = A * a
    if A == B:
        result = "YES"
        break
    i += 1
print result
看了下其他正确答案,基本都是用这个方法。



6.

牛牛有N个字符串,他想将这些字符串分类,他认为两个字符串A和B属于同一类需要满足以下条件:
A中交换任意位置的两个字符,最终可以得到B,交换的次数不限。比如:abc与bca就是同一类字符串。
现在牛牛想知道这N个字符串可以分成几类。 
输入描述:
首先输入一个正整数N(1 <= N <= 50),接下来输入N个字符串,每个字符串长度不超过50。


输出描述:
输出一个整数表示分类的个数

个人思路:

又是这一类的题,set list

正确答案(本人):

n = int(raw_input())
i = 0
arr = []
while i < n:
    s = raw_input()
    str = ''.join(sorted(s))
    arr.append(str)
    i += 1
print len(set(arr))



7.

众所周知计算机代码底层计算都是0和1的计算,牛牛知道这点之后就想使用0和1创造一个新世界!牛牛现在手里有n个0和m个1,给出牛牛可以创造的x种物品,每种物品都由一个01串表示。牛牛想知道当前手中的0和1可以最多创造出多少种物品。 
输入描述:
输入数据包括x+1行:

第一行包括三个整数x(2 ≤ x ≤ 20),n(0 ≤ n ≤ 500),m(0 ≤ m ≤ 500),以空格分隔

接下来的x行,每行一个01串item[i],表示第i个物品。每个物品的长度length(1 ≤ length ≤ 50)


输出描述:
输出一个整数,表示牛牛最多能创造多少种物品

个人思路:

题是读懂了,但面对很多 01 还是不知道怎么去解决。现在一看解析,下面大佬们无一例外的都展示了对01背包算法的讲解。

正确答案(牛客网 id:zero_python):

x, n, m = map(int, raw_input().strip().split())
 
from collections import Counter
goods = [Counter(raw_input().strip()) for _ in range(x)]
 
def backtrace(goods, l, index, n, m, cur, best):
    if index < l:
        if l-index + cur <= best:
            return best
        good = goods[index]
        zero = good.get('0', 0)
        one = good.get("1", 0)
        if zero <= n and one <= m:
            best = backtrace(goods, l, index+1, n-zero, m-one, cur+1, best) # 制作
        return backtrace(goods, l, index+1, n, m, cur, best) # 不制作
    else:
        return max(cur, best)
     
print backtrace(goods, len(goods), 0, n,m, 0, 0)
Counter :跟踪值出现的次数
>>> c = Counter ( "abcdefgab" )
>>> c [ "a" ]
2
>>> c [ "c" ]
1
>>> c [ "h" ]
0
这里采用了递归算法。
一个物品的 0 1 数量为 zero one ,如果比 n m 小,则就可以制作。看懂了!
这是灵活使用了 python 的库的典型例子!



8.

牛牛在书上看到一种字符串叫做回文串,当一个字符串从左到右和从右到左读都是一样的,就称这个字符串为回文串。牛牛又从好朋友羊羊那里了解到一种被称为优美的回文串的字符串,考虑一个长度为N只包含大写字母的字符串,写出它所有长度为M的连续子串(包含所有可能的起始位置的子串,相同的子串也要计入),如果这个字符串至少有K个子串都是回文串,我们就叫这个字符串为优美的回文串。现在给出一个N,牛牛希望你能帮他计算出长度为N的字符串有多少个是优美的回文串(每个位置都可以是'A'~'Z'的一个。) 
输入描述:
输入数据包括三个整数N, M, K(2 ≤ N ≤ 11, 2 ≤ M ≤ N, 0 ≤ K ≤ 11).


输出描述:
输出一个整数,表示所求的字符串个数

个人思路:

此题虽然描述很长,但是就一个主要难点:只给了字符串长度,列出所有字符串,26个大写英文字母组成的啊。幸好长度限制了范围。所有连续字串前面也做过,判断回文也不难。因此,如何解决根据长度得出所有字符串,是重中之重。

正确答案:

暂无。
def judge_huiwen(n):
    arr = list(n)
    j = len(arr) - 1
    flag = True
    for i in range(0, len(arr)/2):
        if arr[i] != arr[j]:
            flag = False
            break
        j -= 1
    return flag


def son(s, m):
    arr = []
    i = 0
    j = m
    while j <= len(s):
        temp = s[i:j]
        arr.append(temp)
        i += 1
        j += 1
    return arr


arr = [int(i) for i in raw_input().strip().split()]
N, M, K = arr[0], arr[1], arr[2]
s = ['A'] * int(N)
temp = s[:]
i = 0
j = 0
all = []
while i < N:
    temp = temp[:]
    temp[j] = chr(ord(temp[j]) + 1)
    all.append(temp)
    j += 1
    if j == N:
        i += 1
        j = 0
print all
我个人果然是奋斗到罗列所有 N 长度的字符串时,卡住了,这就是又是全排列问题了,对,这次真要看全排列。简直真的是所有排列
AAAAAA
AAAAAB
AAAABB
.............
子子孙孙无穷尽也












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值