20200418京东算法暑期实习笔试 Python3

第一题

题目描述

给出平面上的2n个点,你可以将这2n个点每两个匹配到一起得到n条线段,请你计算一种匹配方式,使得你得到的这n条线段,平行的线段对数最多。

输入描述

第一行包含-个整数2n, 2 < = 2 n < = 16 2 <= 2n <= 16 2<=2n<=16
接下来2n行,每行包含两个整数x, y,表示一个点的坐标。
− 1000 < = x , y < = 1000 -1000 <= x,y <= 1000 1000<=x,y<=1000
保证所有的点都不重合,并且没有三点共线

输出描述

输出最多能有多少对线段平行。

示例输入

8
0 0
0 5
2 2
2 7
3 -2
5 0
4 -2
8 2

示例输出

6

解释

最多可以画出四条两两相互平行的线段,结果为 C 4 2 = 6 C_{4}^{2} = 6 C42=6

思路

所有的点都不重合,并且没有三点共线
这一点很重要,使得题目简化了很多。
并且点最多16个,基本不用考虑算法复杂度。
步骤:
1、任选两个点组成一条直线,计算斜率并记录下来
2、剩下的2n-2个点两两组合计算斜率,若等于1中的斜率,则计数加1,共计算 C 2 n − 2 2 C_{2n-2}^{2} C2n22次,将最终计数保存进数组
3、将步骤1、2计算 C 2 n 2 C_{2n}^{2} C2n2次,生成长度为 C 2 n 2 C_{2n}^{2} C2n2的数组
该数组中的最大值就是斜率相同的最多线段数量
返回 C m a x 2 C_{max}^{2} Cmax2

代码

n = int(input())
list_x = [0] * n
list_y = [0] * n
for i in range(n):
    list_x[i], list_y[i] = list(map(int, input().split()))
# print(list_x)
# print(list_y)
k_num = []
for u in range(n - 1):
    for v in range(u + 1, n):
        res = (list_y[v] - list_y[u]) / (list_x[v] - list_x[u]) if list_x[v] != list_x[u] else float('inf')
        num = 1
        for i in range(n - 1):
            for j in range(i + 1, n):
                if i == u or i == v or j == u or j == v: continue
                xxx = (list_y[j] - list_y[i]) / (list_x[j] - list_x[i]) if list_x[j] != list_x[i] else float('inf')
                if res == xxx: num += 1
        k_num.append(num)
# print(k_num)
k_num_max = max(k_num)
print(k_num_max * (k_num_max - 1) // 2)

没有用评测系统验证,通过率未知,如有特例遗漏,还望大佬指正

第二题

题目描述

小A持有n支股票,行情不好,每股都在下跌。小A想抛售股票,可是被交易所限制,每天最多只能卖出m支股票。
现在他还没有决定具体卖出多少支股票,所以他会给你若干个询问,即如果卖出q支股票,这q支股票最少的亏损数额是多少元。

输入描述

输入第一行包含两个正整数n和m,表示小A持仓的股票数量和每天最多能卖出的股票数量。( 1 < = n , m < = 50000 1<=n,m<= 50000 1<=n,m<=50000)
输入第二行包含n个正整数,第i个数 a i a_i ai表示第i支股票每天的亏损数额。(1<= a i a_i ai<= 10000)
接下来一行有一个正整数Q,表示询问的数量。( 1 < = Q < = 50000 1<=Q<= 50000 1<=Q<=50000)
之后有Q行,每行有一个正整数q,表示假如要卖出q支股票,最少的亏损数额是多少元。( q < = n q<=n q<=n)

输出描述

对于每个询问,输出对应的结果。

示例输入

5 2
1 2 3 4 5
2
3
5

示例输出

7
22

思路

暴力计算超时,还没想到好的思路。

代码

n, m = list(map(int, input().split()))
list_n = list(map(int, input().split()))
list_n.sort()
q = int(input())
ask = []
for _ in range(q):
    ask.append(int(input()))
# print(list_n, ask)

def f(x):
    list1 = list_n[0:x]
    num = len(list1) // m
    res = 0
    for i in range(num):
        res += sum(list1[len(list1) - m * (i + 1):len(list1) - m * i]) * (i + 1)
    if len(list1) % m:
        res += sum(list1[:-num * m]) * (num + 1)
    return res

for i in ask:
    print(f(i))

超时,只通过27%。还是太菜。

最后一句

京东笔试太难了,被虐到怀疑人生

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值