2017年校招全国统一模拟笔试(第四场)编程题集合--Python
Posted zy_dream
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017年校招全国统一模拟笔试(第四场)编程题集合--Python相关的知识,希望对你有一定的参考价值。
注:试题来源于牛客网
1.
牛牛有n张卡片排成一个序列.每张卡片一面是黑色的,另一面是白色的。初始状态的时候有些卡片是黑色朝上,有些卡片是白色朝上。牛牛现在想要把一些卡片翻过来,得到一种交替排列的形式,即每对相邻卡片的颜色都是不一样的。牛牛想知道最少需要翻转多少张卡片可以变成交替排列的形式。输入描述:
输入包括一个字符串S,字符串长度length(3 ≤ length ≤ 50),其中只包含'W'和'B'两种字符串,分别表示白色和黑色。整个字符串表示卡片序列的初始状态。
输出描述:
输出一个整数,表示牛牛最多需要翻转的次数。
输入例子1:
BBBW
输出例子1:
1
个人思路:
有两个思路 1.根据第一位,把正确排列弄出来。然后与输入的字符串遍历比较,得出结果2.设一个 flag = BW and flag = WB,依次用切片取两个字符,比较,不相同的话,count += 1。最后取两个中的最小值
正确答案(本人&&牛客网id:liberty_zheng):
flag1, flag2, flag3, flag4, flag5, flag6 = 'BW', 'WB', 'BB', 'WW', 'B', 'W'
def bw_start(arr):
i, j = 0, 2
bw = 0
while j <= len(arr)+2:
temp = ''.join(arr[i:j])
if temp == flag1:
i += 2
j += 2
continue
elif temp == flag2:
bw += 2
elif temp == flag3 or temp == flag4:
bw += 1
elif temp == flag6:
bw += 1
i += 2
j += 2
return bw
def wb_start(arr):
i, j = 0, 2
wb = 0
while j < len(arr):
temp = ''.join(arr[i:j])
if temp == flag2:
i += 2
j += 2
continue
elif temp == flag1:
wb += 2
elif temp == flag3 or temp == flag4:
wb += 1
elif temp == flag5:
wb += 1
i += 2
j += 2
return wb
string = raw_input()
arr = list(string)
result = (bw_start(arr), wb_start(arr))
print min(result)
我用了第二种思路,就是 flag 立的有点多啦
data=raw_input()
counts1=0
counts2=0
for i in range(len(data)):
if i%2==0:
if data[i]=='B':
continue
else:
counts1+=1
else:
if data[i]=='W':
continue
else:
counts1+=1
print min(counts1,len(data)-counts1)
网上同学是采用相当于第一种思路
2.
牛牛变得黑化了,想要摧毁掉地球。但他忘记了开启地球毁灭器的密码。牛牛手里有一个字符串S,牛牛还记得从S中去掉一个字符就恰好是正确的密码,请你帮牛牛求出他最多需要尝试多少次密码。如样例所示S = "ABA",3个可能的密码是"BA", "AA", "AB".
当S = "A", 牛牛唯一可以尝试的密码是一个空的密码,所以输出1.
输入描述:
输入包括一个字符串S,字符串长度length(1 ≤ length ≤ 50),其中都是从'A'到'Z'的大写字母。
输出描述:
输出一个整数,表示牛牛最多需要尝试的密码次数。
输入例子1:
ABA
输出例子1:
3
个人思路:
我的思路太简单,对题的理解就是,一个字符串去掉一个字符后的所有排列组合。 对于又看到排列组合,我分分钟就用了 Python 强大的库 itertools.permutations(arr, num) 。 但结果,超内存啦 再看同学思路,如果相邻的两个字符串相同,那么去除任意一个,效果都是一样的 没有重复的,次数就是字符串长度。这句才是重点。正确答案(牛客网id:liberty_zheng):
data=raw_input()
count=len(data)
for i in range(1,len(data)):
if data[i]==data[i-1]:
count-=1
print count
只能说我太依赖有些东西了。
3.
牛牛以草料为食。牛牛有一天依次遇到n堆被施展了魔法的草料,牛牛只要遇到一堆跟他当前相同大小的草料,它就会把草料吃完,而使自己的大小膨胀一倍。一开始牛牛的大小的是A,然后给出牛牛依次遇到的n堆草料的大小。请计算牛牛最后的大小。输入描述:
输入包括两行,第一行包含两个整数n和A(1 ≤ n ≤ 200, 1 ≤ A ≤ 1,000,000,000) 第二行包括n个整数,表示牛牛依次遇到的草料堆大小a_i(1 ≤ a_i ≤ 1,000,000,000)
输出描述:
输出一个整数,表示牛牛最后的大小。
输入例子1:
5 1 2 1 3 1 2
输出例子1:
4
个人思路:
很简单的一题,遇见相同的翻倍即可。正确答案(本人):
ab = [int(i) for i in raw_input().strip().split()]
arr = [int(i) for i in raw_input().strip().split()]
A = ab[1]
for i in range(ab[0]):
if arr[i] == A:
A = A * 2
print A
4.
牛牛有一个长度为n的整数序列s,羊羊要在牛牛的序列中选择不同的两个位置,然后交换这两个位置上的元素。现在需要求出羊羊交换后可以得到的不同的序列个数。(注意被交换的两元素值可能相同)。如序列1, 47,输出1.羊羊必须交换仅有的两个元素,得到序列47, 1。羊羊必须交换,不能保留原有的序列。
1, 2, 1,输出3.羊羊通过交换可以得到2, 1, 1,1, 1, 2,1, 2, 1这三个序列。
输入描述:
输入包括两行,第一行为一个整数n(2 ≤ n ≤ 50),即序列的长度。 第二行n个整数,表示序列的每个元素a_i(1 ≤ a_i ≤ 50),以空格分割。
输出描述:
输出一个整数,表示羊羊可以得到的不同的序列个数
输入例子1:
3 1 2 1
输出例子1:
3
个人思路:
难得这道题我居然用了数学中的找规律,想也没想就直接放上了找出的规律,40% casen = int(raw_input())
arr = [int(i) for i in raw_input().strip().split()]
result = n * (n - 1) / 2
然后一看,我是写到重复的问题。但是,我是考虑了重复的问题,而且还列了规律。只是被规律和测试冲昏了头脑
正确答案(牛客网id:Saharayu):
n = int(raw_input())
a_i = map(int,raw_input().split())
m = 0
if len(set(a_i)) == 1:
print 1
else:
for i in range(n):
for j in range(i+1,n):
if a_i[i] == a_i[j]:
m = m + 1
if m != 0:
print n*(n-1)/2 - m + 1
else:
print n*(n-1)/2
找出重复的次数,最后 - m + 1 即可。
5.
牛牛喜欢字符串,但是他讨厌丑陋的字符串。对于牛牛来说,一个字符串的丑陋值是字符串中相同连续字符对的个数。比如字符串“ABABAABBB”的丑陋值是3,因为有一对"AA"和两对重叠的"BB"。现在给出一个字符串,字符串中包含字符'A'、'B'和'?'。牛牛现在可以把字符串中的问号改为'A'或者'B'。牛牛现在想让字符串的丑陋值最小,希望你能帮帮他。输入描述:
输入包括一个字符串s,字符串长度length(1 ≤ length ≤ 50),字符串只包含'A','B','?'三种字符。
输出描述:
输出一个整数,表示最小的丑陋值
输入例子1:
A?A
输出例子1:
0
个人思路:
倒也想到了判断 ? 前后的 AB,然后怎么怎么操作的。但自己又被自己阻碍了。最后没有再去想。正确答案(牛客网id:大虫逗你玩):
import sys
str = raw_input()
arr = list(str)
length = len(arr)
count = 0
for i in range(1,len(arr)):
if arr[i] == "?":
if arr[i-1] == "A":
arr[i] = "B"
elif arr[i-1] == "B":
arr[i] = "A"
for i in range(0,length-1):
if arr[i] == arr[i+1] and arr[i]!="?":
count = count + 1
print count
这个思路简单啊,就没有想太多。问号的前一个,来设置 ? 的值,最后来判断丑陋值。但这是怎么确定最小的呢?或许根本不用考虑最小。
6.
牛家庄幼儿园为庆祝61儿童节举办庆祝活动,庆祝活动中有一个节目是小朋友们围成一个圆圈跳舞。牛老师挑选出n个小朋友参与跳舞节目,已知每个小朋友的身高h_i。为了让舞蹈看起来和谐,牛老师需要让跳舞的圆圈队形中相邻小朋友的身高差的最大值最小,牛老师犯了难,希望你能帮帮他。如样例所示:
当圆圈队伍按照100,98,103,105顺时针排列的时候最大身高差为5,其他排列不会得到更优的解
输入描述:
输入包括两行,第一行为一个正整数n(3 ≤ n ≤ 20) 第二行为n个整数h_i(80 ≤ h_i ≤ 140),表示每个小朋友的身高。
输出描述:
输出一个整数,表示满足条件下的相邻小朋友身高差的最大值。
输入例子1:
4 100 103 98 105
输出例子1:
5
个人思路:
想法过于简单,只想到数组的排列组合列举到明年的情况。没有去想,什么样的排列才可以得到要求。 排好序之后,一句话:由高向低的扩散,即为所求答案正确答案(牛客网id:大虫逗你玩):
n = int(raw_input())
a = [int(s) for s in raw_input().split()]
a.sort()
max_v = 0
for i in range(2, n):
v = a[i] - a[i-2]
if v > max_v:
max_v = v
print max_v
所以,转化而知,就是求排序后间隔为2的最大的差。
7.
有一条无限长的纸带,分割成一系列的格子,最开始所有格子初始是白色。现在在一个格子上放上一个萌萌的机器人(放上的这个格子也会被染红),机器人一旦走到某个格子上,就会把这个格子涂成红色。现在给出一个整数n,机器人现在会在纸带上走n步。每一步,机器人都会向左或者向右走一个格子,两种情况概率相等。机器人做出的所有随机选择都是独立的。现在需要计算出最后纸带上红色格子的期望值。输入描述:
输入包括一个整数n(0 ≤ n ≤ 500),即机器人行走的步数。
输出描述:
输出一个实数,表示红色格子的期望个数,保留一位小数。
输入例子1:
4
输出例子1:
3.4
个人思路:
看到期望,还特地的去搜了一下期望怎么求。果然世界处处皆数学啊。请同学们自行复习期望。正确答案(牛客网id:草莓冰淇淋):
def main():
n = int(raw_input())
print round(trans(n), 1)
def trans(n):
if n == 0:
return 1.0
elif n == 1:
return 2.0;
elif n%2 == 1:
return trans(n-1)*(2*n)/(2*n-1);
elif n%2 == 0:
return trans(n-1)*(2*n+1)/(2*n);
main()
用了递归。我现在的问题在于我不知道递归怎么结束啊。
8.
牛牛在农场饲养了n只奶牛,依次编号为0到n-1, 牛牛的好朋友羊羊帮牛牛照看着农场.有一天羊羊看到农场中逃走了k只奶牛,但是他只会告诉牛牛逃走的k只奶牛的编号之和能被n整除。你现在需要帮牛牛计算有多少种不同的逃走的奶牛群。因为结果可能很大,输出结果对1,000,000,007取模。例如n = 7 k = 4:
7只奶牛依次编号为0到6, 逃走了4只
编号和为7的有:0, 1, 2, 4
编号和为14的有:0, 3, 5, 6, 1, 2, 5, 6, 1, 3, 4, 6,2, 3, 4, 5
4只牛的编号和不会大于18,所以输出5.
输入描述:
输入包括一行,两个整数n和k(1 ≤ n ≤ 1000),(1 ≤ k ≤ 50),以空格分割。
输出描述:
输出一个整数表示题设所求的种数。
输入例子1:
7 4
输出例子1:
5
个人思路:
题很好懂很好理解,又有大数据问题。然后看了下面同学们的思路,一把辛酸泪正确答案(牛客网id:牛客4808019):
#include<iostream>
using namespace std;
const int mod=1e9+7;
//看了楼上各位大神的代码和注释,写了一点粗鄙之见。。
//这个是通过状态压缩之后的形式了,最初的形式应该是dp[i][j][s],代表的含义是从[0,i]中取j个数,使他们的和模n的余数为s,这样的j个数的集合的个数
//状态转移方程为dp[i][j][s]=dp[i-1][j][s]+dp[i-1][j-1][(s-i+n)%n];
//转移的过程就是对于第i个数,取还是不取,如果不取,那么方案数就和i-1时的方案数相同
//如果取i的话,那么分两种情况分析,第一种情况是i<=s,此时我们需要求从前i-1个数中,取j-1个数,使得他们的和模n的余数为s-i,这样就能保证在加入i时,和模n为s
//第二种情况是i>s,那么s-i为负数,注意到本题要求的是组成和为n的倍数,也即所有模n为0的数,因此这种情况下将(s-i)%n表示成(s-i+n)%n即可满足要求,因为((s-i+n)%n+i)%n=s;
//这个式子对于第一种情况也成立,因此和在一起就好了
int dp[55][1005];
int main()
int n,k;
while(cin>>n>>k)
dp[0][0]=1;
for(int i=0;i<n;i++)
for(int j=k;j>=1;j--)//状态压缩,道理和01背包一样
for(int s=0;s<n;s++)
dp[j][s]=(dp[j][s]+dp[j-1][(n+s-i)%n])%mod;
cout<<dp[k][0]<<endl;//最后输出取k个使他们的和模n的余数为0的所有集合的数目
return 0;
我是一只小小小小鸟。
以上是关于2017年校招全国统一模拟笔试(第四场)编程题集合--Python的主要内容,如果未能解决你的问题,请参考以下文章
2017年校招全国统一模拟笔试(第二场)编程题集合--Python
2017年校招全国统一模拟笔试(第三场)编程题集合--Python
2017年校招全国统一模拟笔试(第三场)编程题集合--Python