题目都偏规律总结类型,只要思路对了,很容易做出来,不像华为机试一道字符串+两道算法题……
第一题
有n个同学,老师买了n块巧克力(1<n<10^5),按照学号顺序依次来办公室拿巧克力,每个进办公室的学生最少拿1块,拿完后面的同学就不用进来了。如果第一个同学至少拿6块的话,剩下同学的分配方案有几种?(结果可能很大,输出对666666666取模的结果)
输入:6 输出:1
输入:8 输出:4 输出说明:8;7,1;6,2;6,1,1;
import sys
while True:
n = sys.stdin.readline()
if n == '':
break
n = int(n)-6
print(0) if n<0 else print(2**n%666666666)
第二题
给出n*2个杯子,每个杯子容量为ai,以及w毫升的水,有n个男孩,n个女孩,规则如下:
-每个男孩子杯里的水要相同
-每个女孩子也要相同
-男孩子的水要是女孩子的水的两倍
问最多总共能倒入多少毫升水?
输入描述:
第一行为两个整数 n 和 w (1<=n<=10^5 , 1<=w<=10^9)
第二行为2n个整数 a1,a2,…,an(1<=ai<=10^9)(每个杯子最大能盛多少水)
示例1 | 示例2 | |
输入 | 2 4 | 3 18 |
1 1 1 1 | 4 4 4 2 2 2 | |
输出 | 3.000000 | 18.000000 |
思路:这个题的意思应该是杯子大小是由答题者来分配的,最优策略就是把最小的n个分配给女生,剩下的给男生。
然后如果女生的最小容量a的二倍>男生最小容量b,那就是男生都获得男生最小容量b,女生都获得b/2
否侧,就是女生都获得a,男生都获得2a
import sys
while True:
inputNum = sys.stdin.readline()
if inputNum == '':
break
n = int(inputNum.split()[0])
w = int(inputNum.split()[1])
a = [int(i) for i in sys.stdin.readline().split()]
a.sort()
if a[0]*2<=a[n+1]:#如果女生最小容量的二倍小于男生最小容量
amount = a[0]*3*n
else:
amount = a[n+1]/2*3*n
if amount>w:
amount = w
print('%.6f'%amount)
第三题
更新:
这道题没来得及提交系统,所以不知道是否case100%,后来经过同学提醒,在nod上找到原题:nod 1483,将原解法提交后,获得了17/20的通过率,原因如下:
解法1的思路,只能应对那种需要调整为2的整数次幂的情况,但是没有考虑30,60这种倍数的情况,也没有98,99这种经过几次对2取整之后相同的情况。正确的解法还是要用暴力搜索列举,然后找最少操作数
使用暴力枚举的解法见下一篇博客
有n瓶试剂,第i瓶中有ai升的试剂,每次可以对其中一瓶进行如下操作:
- 使其剂量翻倍
- 使其剂量减半(其实题目是对2取整)
问多少次操作后,可以将所有瓶中试剂含量相等。(1<n<10^5, 1<ai<10^5)
示例1 | 示例2 | |
输入 | 3 | 3 |
4 8 2 | 3 5 6 | |
输出 | 2 | 5 |
大概思路:将所有数字调整为2的整数次幂(如果不是2的整数次幂就需要对2取整,直到其变成2的整数次幂),并将其是第几次幂存下来,然后就能转化为n个数通过+1-1调整为一样的值,代码如下:(注意:该解法考虑步骤,只有80%的通过率)
import sys
num_2n = [2**n for n in range(17)]
while True:
count = 0
des = list()
n = sys.stdin.readline()
if n == '':
break
n = int(n)
num = [int(i) for i in sys.stdin.readline().split()]
for i in range(n):
while num[i] not in num_2n:
num[i] = num[i]//2
count += 1
des.append(num_2n.index(num[i]))
a = sum(des)//n
for i in des:
count += abs(a-i)
print(count)