A 乐奈吃冰

。。。

a,b = map(int,input().strip().split())
print(a + min(a // 2,b))

B 素世喝茶

。。。

n,x = map(int,input().strip().split())
a = list(map(int,input().strip().split()))
x -= 1
t_max = a[0]
t = 0
for i,num in enumerate(a):
    if i == x:
        continue
        
    if num == t_max:
        t += 1
    elif num > t_max:
        t_max = num
        t = 1
print(t)

C 爱音开灯

获取x的所有因数,判断有多少个因数在[1,n]范围内,若在范围内则会被开/关灯一次

n,x = map(int,input().strip().split())

if x == 1:
    t = 1
else:
    d = 2
    t = 0
    if 1 <= n:
        t += 1
    
    if x <= n:
        t += 1
        
    while d * d <= x:
        if x % d == 0:
            if d <= n:
                t += 1
                
            if d * d != x:
                if x // d <= n:
                    t += 1
        d += 1


if t&1:
    print("ON")
else:
    print("OFF")
    

D 小灯做题

分情况讨论,详情见代码。。。

T = int(input())
for _ in range(T):
    a,b,c,k = map(int,input().strip().split())
    arr = [a,b,c]
    if k in arr:
        print(0)
    elif not k:
        print(1)
    elif k == 2:
        if 0 in arr and 1 in arr:
            print(1)
        elif 0 in arr and 1 not in arr:
            print(2)
        elif 0 not in arr and 1 in arr:
            print(2)
        else:
            print(3)
    elif k == 1:
        if 0 in arr:
            print(1)
        else:
            print(2)
    else:
        print(-1)

E 立希喂猫

排序

按每种猫粮的数目从小到大进行排序

二分搜索

根据天数k值,对排序后的数组进行二分搜索得到pospos左边的猫粮会被全部吃完,pos右边的猫粮每一种都能吃k

简简单单前缀和

  • left 代表猫粮会被全部吃完的价值前缀和
  • right 代表猫粮会只被吃一次的价值前缀和
n = int(input())
A = list(map(int,input().strip().split()))
B = list(map(int,input().strip().split()))

arr = list(zip(B,A))

arr.sort()
# print(arr)

# 猫粮会被全部吃完的前缀和
left = [0] * (n+1)

# 每种只吃一次的前缀和
right = [0] * (n+1)
for i,(b,a) in enumerate(arr):
    left[i+1] = left[i] + a*b
    right[i+1] = right[i] + a

# print(left,right)

import bisect
q = int(input())
while q:
    k = int(input())
    # 二分搜索
    pos = bisect.bisect_right(arr,(k,int(1e10)))
    res = left[pos] + (right[-1] - right[pos]) * k
    print(res)
    
    q -= 1

F 祥子拆团

因数分解

x进行因数分解,因数分解不包含1,如8分解:

8 = 2 * 2 * 2
8 = 2 * 4
8 = 4 * 2
8 = 8

dfs即可:

# 因数分解
@lru_cache(None)
def dfs(num,i,y):
    if num == 1:
        return myComb(y,i)
    
    res = 0
    res += dfs(1,i+1,y)
    if i + 1 != y:
        d = 2
        while d * d <= num:
            if num % d == 0:
                res += dfs(d,i+1,y)
                if d * d != num:
                    res += dfs(num//d,i+1,y)
                res %= mod
            d += 1
    return res

当然要加个记忆化搜索。

组合数学

假设分解成i个数相乘,则其它空余位置补1,即C(y,i),逆元和组合数学解决

最终代码

呵呵,pypy3竟然没超时。

T = int(input())
mod = int(1e9+7)

# 预处理阶乘以及其逆元
max_n = int(2*1e5)
fac = [1] * (max_n+1)
facinv = [1] * (max_n+1)

for i in range(1,max_n+1):
    fac[i] = fac[i-1] * i % mod
    # python自带快速幂
    facinv[i] = pow(fac[i],mod-2,mod)

from functools import lru_cache
@lru_cache(None)
def myComb(n,m):    
    if m < 0 or n < m:
        return 0
    
    if n - m < m:
        m = n - m
    
    res = 1
    for i in range(m):
        res *= n-i
        res %= mod
        
    return res * facinv[m] % mod

# 因数分解
@lru_cache(None)
def dfs(num,i,y):
    if num == 1:
        return myComb(y,i)
    
    res = 0
    res += dfs(1,i+1,y)
    if i + 1 != y:
        d = 2
        while d * d <= num:
            if num % d == 0:
                res += dfs(d,i+1,y)
                if d * d != num:
                    res += dfs(num//d,i+1,y)
                res %= mod
            d += 1
    return res
    
for _ in range(T):
    x,y = map(int,input().strip().split())
    print(dfs(x,0,y))