1 条题解

  • 0
    @ 2023-2-9 17:11:16

    对行数进行二分,找到目标所在行

    def C(m, n):
        ans = 1
        for j in range(1, n+1):
            ans  = ans * (m - (j -1)) / j
            if ans > N: # 加快运算,大于时直接抛出
                return -1
        return ans
    
    
    def check(mid):
        if C(mid, (mid+1) // 2) < N:  # 该行最大值小于目标
            return -1
     
        for j in range((mid+1)//2 + 1):
            t = C(mid, j)
            if t == N:  # 该行找到了
                return 0
            elif t == -1: # 该行最大值大于目标
                return 1
    
        
    
    
    
    T = int(input())
    
    while T > 0:
        T -= 1
    
        N = int(input())
        
        l, r =0, N  # 二分上限是N
        
        while l <= r:
            
            mid = (l + r) >> 1
            
            ans = check(mid)
            if ans == 1:  # 该行没有找到,且最大值大于目标
                r = mid - 1
            elif ans == -1: # 没找到,小于
                l = mid + 1
            else:  # 找到了,退出
                break
                
                
        if l > r:  # 特殊情况,目标就在第N行
            mid = N
    
    
    #根据行数,找到目标在数列中位置
        s = (1 + mid) * mid  // 2  
        for j in range((mid + 1) // 2 + 1):
            if C(mid, j) == N:
                s += (j + 1)
                break
        print(s)
    

    借鉴了这个博主的思路,主要是这张图。 但我不是很认同对’列‘进行二分的想法 image

    • 1

    信息

    ID
    19
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    (无)
    递交数
    19
    已通过
    5
    上传者