分巧克力&&直线

题目

小明一共有 N 块巧克力,其中第 i 块是 Hi​×Wi 的方格组成的长方形。为了公平起见,

小明需要从这 N 块巧克力中切出 K 块巧克力分给小朋友们。切出的巧克力需要满足:

  1. 形状是正方形,边长是整数;

  2. 大小相同;

例如一块 6x5 的巧克力可以切出 6 块 2x2 的巧克力或者 2 块 3x3 的巧克力。

当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?

思路

        太久没做过这些题目了,拿到题目一脸茫然。以为是从现有的巧克力大小去计算能够生成的正方形个数,直到正方形的个数>人数。但这样其实很不好想,就是代码也不知道咋写。就去看了题解,发现是暴力!我只能说暴力解法,yyds。暴力的去遍历每个边长,检查当前巧克力分为当前边长的小块能够分为几块,为了提高效率,使用二分法进行查找。

        还有个点就是,能够分为的边长为a的正方形个数 = (大块的长)//(a) * (大块的宽)//(a)  

代码

import os
import sys

# 请在此输入您的代码

N, K = map(int, input().split())
datas = []

for i in range(N):
  datas.append(list(map(int, input().split())))

def serch():
  # 经典二分法写法 这里需要注意的就是返回的是l 还是mid 还是r
  # 最后的结果肯定跟这些有关系 如果考试的时候不知道怎么去判断逻辑 可以都输出来 看看规律
  # 这里输出的是l-1 ,带入一个简单的运算一遍 就会发现 退出循环的时候 那个值在l的左边
  l = 1
  r = 100000
  while(l <= r):
    mid = (l + r) // 2
    if(check(mid)):
      l = mid + 1
    else:
      r = mid - 1
  return l-1


def check(a):  
  # 传入切割巧克力的边长a 判断当前边长能够切多少块
  num = 0
  for data in datas:
    num += (data[0] // a) * (data[1] // a)

  if num >= K:
    return True
  else:
    return False

print(serch())

题目

在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上, 那么这些点中任意两点确定的直线是同一条。

给定平面上 20×2120×21 个整点 (x,y)∣0≤x<20,0≤y<21,x∈Z,y∈Z,即横 坐标是 00 到 19 (包含 0 和 19) 之间的整数、纵坐标是 0 到 20 (包含 0 和 20​) 之 间的整数的点。

请问这些点一共确定了多少条不同的直线。

思路

        直线是由斜率和b决定的,即只需要算出任意两点之间的斜率k和b,就能得到直线的条数。但是不知道怎么去遍历每个点,看了别人的题解才发现[[x,y] for x in range(20) for y in range(21)]就能遍历出所有的节点坐标。呜呜呜 我好菜 

代码

import os
import sys

# 请在此输入您的代码
points = [[x,y]for x in range(20) for y in range(21)]
out = set()

for x in points:
  for y in points:
    if x[0] == y[0]:
      continue
    else:
      k = (y[1] - x[1]) / (y[0] - x[0])
      b = (y[0]*x[1] - x[0]*y[1])/(y[0] - x[0])
      out.add((k,b))

print(len(out) + 20)
# 20是斜率不存在的情况
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值